Imported Upstream version 2.4.4p3 upstream/2.4.4p3
authorBdale Garbee <bdale@gag.com>
Tue, 20 May 2008 04:46:33 +0000 (22:46 -0600)
committerBdale Garbee <bdale@gag.com>
Tue, 20 May 2008 04:46:33 +0000 (22:46 -0600)
349 files changed:
AUTHORS [new file with mode: 0644]
COPYRIGHT [new file with mode: 0644]
COPYRIGHT-APACHE [new file with mode: 0644]
COPYRIGHT-REGEX [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
acinclude.m4 [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
amplot/Makefile.am [new file with mode: 0644]
amplot/Makefile.in [new file with mode: 0644]
amplot/amcat.awk.in [new file with mode: 0644]
amplot/amplot.awk [new file with mode: 0644]
amplot/amplot.g [new file with mode: 0644]
amplot/amplot.sh.in [new file with mode: 0644]
changer-src/Makefile.am [new file with mode: 0644]
changer-src/Makefile.in [new file with mode: 0644]
changer-src/chg-chio.pl.in [new file with mode: 0644]
changer-src/chg-chs.sh.in [new file with mode: 0644]
changer-src/chg-disk.sh.in [new file with mode: 0644]
changer-src/chg-iomega.pl.in [new file with mode: 0644]
changer-src/chg-juke.sh.in [new file with mode: 0755]
changer-src/chg-manual.sh.in [new file with mode: 0644]
changer-src/chg-mcutil.sh.in [new file with mode: 0644]
changer-src/chg-mtx.sh.in [new file with mode: 0644]
changer-src/chg-multi.sh.in [new file with mode: 0644]
changer-src/chg-null.sh.in [new file with mode: 0644]
changer-src/chg-rait.sh.in [new file with mode: 0644]
changer-src/chg-rth.pl.in [new file with mode: 0644]
changer-src/chg-scsi-chio.c [new file with mode: 0644]
changer-src/chg-scsi.c [new file with mode: 0644]
changer-src/chg-zd-mtx.sh.in [new file with mode: 0644]
changer-src/libscsi.h [new file with mode: 0644]
changer-src/scsi-aix.c [new file with mode: 0644]
changer-src/scsi-bsd.c [new file with mode: 0644]
changer-src/scsi-cam.c [new file with mode: 0644]
changer-src/scsi-changer-driver.c [new file with mode: 0644]
changer-src/scsi-chio.c [new file with mode: 0644]
changer-src/scsi-defs.h [new file with mode: 0644]
changer-src/scsi-hpux.c [new file with mode: 0644]
changer-src/scsi-hpux_new.c [new file with mode: 0644]
changer-src/scsi-irix.c [new file with mode: 0644]
changer-src/scsi-linux.c [new file with mode: 0644]
changer-src/scsi-proto.c [new file with mode: 0644]
changer-src/scsi-solaris.c [new file with mode: 0644]
changer-src/sense.c [new file with mode: 0644]
client-src/Makefile.am [new file with mode: 0644]
client-src/Makefile.in [new file with mode: 0644]
client-src/amandad-krb4.c [new file with mode: 0644]
client-src/amandad.c [new file with mode: 0644]
client-src/amandates.c [new file with mode: 0644]
client-src/amandates.h [new file with mode: 0644]
client-src/amhpfixdevs.sh [new file with mode: 0644]
client-src/amqde.c [new file with mode: 0644]
client-src/amsinixfixdevs.sh [new file with mode: 0644]
client-src/calcsize.c [new file with mode: 0644]
client-src/client_util.c [new file with mode: 0644]
client-src/client_util.h [new file with mode: 0644]
client-src/findpass.c [new file with mode: 0644]
client-src/findpass.h [new file with mode: 0644]
client-src/getfsent.c [new file with mode: 0644]
client-src/getfsent.h [new file with mode: 0644]
client-src/killpgrp.c [new file with mode: 0644]
client-src/patch-system.sh.in [new file with mode: 0644]
client-src/rundump.c [new file with mode: 0644]
client-src/runtar.c [new file with mode: 0644]
client-src/selfcheck.c [new file with mode: 0644]
client-src/sendbackup-dump.c [new file with mode: 0644]
client-src/sendbackup-gnutar.c [new file with mode: 0644]
client-src/sendbackup-krb4.c [new file with mode: 0644]
client-src/sendbackup-krb4.h [new file with mode: 0644]
client-src/sendbackup.c [new file with mode: 0644]
client-src/sendbackup.h [new file with mode: 0644]
client-src/sendsize.c [new file with mode: 0644]
client-src/unctime.c [new file with mode: 0644]
client-src/versionsuffix.c [new file with mode: 0644]
common-src/Makefile.am [new file with mode: 0644]
common-src/Makefile.in [new file with mode: 0644]
common-src/alloc.c [new file with mode: 0644]
common-src/alloca.c [new file with mode: 0644]
common-src/amanda.h [new file with mode: 0644]
common-src/amfeatures.c [new file with mode: 0644]
common-src/amfeatures.h [new file with mode: 0644]
common-src/amflock.c [new file with mode: 0644]
common-src/amregex.h [new file with mode: 0644]
common-src/arglist.h [new file with mode: 0644]
common-src/clock.c [new file with mode: 0644]
common-src/clock.h [new file with mode: 0644]
common-src/debug.c [new file with mode: 0644]
common-src/dgram.c [new file with mode: 0644]
common-src/dgram.h [new file with mode: 0644]
common-src/error.c [new file with mode: 0644]
common-src/file.c [new file with mode: 0644]
common-src/fileheader.c [new file with mode: 0644]
common-src/fileheader.h [new file with mode: 0644]
common-src/genversion.c [new file with mode: 0644]
common-src/getcwd.c [new file with mode: 0644]
common-src/krb4-security.c [new file with mode: 0644]
common-src/krb4-security.h [new file with mode: 0644]
common-src/match.c [new file with mode: 0644]
common-src/memmove.c [new file with mode: 0644]
common-src/mktime.c [new file with mode: 0644]
common-src/pipespawn.c [new file with mode: 0644]
common-src/pipespawn.h [new file with mode: 0644]
common-src/protocol.c [new file with mode: 0644]
common-src/protocol.h [new file with mode: 0644]
common-src/regcomp.c [new file with mode: 0644]
common-src/regerror.c [new file with mode: 0644]
common-src/regexec.c [new file with mode: 0644]
common-src/regfree.c [new file with mode: 0644]
common-src/security.c [new file with mode: 0644]
common-src/sl.c [new file with mode: 0644]
common-src/sl.h [new file with mode: 0644]
common-src/snprintf.c [new file with mode: 0644]
common-src/statfs.c [new file with mode: 0644]
common-src/statfs.h [new file with mode: 0644]
common-src/strcasecmp.c [new file with mode: 0644]
common-src/stream.c [new file with mode: 0644]
common-src/stream.h [new file with mode: 0644]
common-src/strerror.c [new file with mode: 0644]
common-src/strftime.c [new file with mode: 0644]
common-src/strncasecmp.c [new file with mode: 0644]
common-src/strstr.c [new file with mode: 0644]
common-src/token.c [new file with mode: 0644]
common-src/token.h [new file with mode: 0644]
common-src/util.c [new file with mode: 0644]
common-src/util.h [new file with mode: 0644]
common-src/version.c [new file with mode: 0644]
common-src/version.h [new file with mode: 0644]
common-src/versuff.c [new file with mode: 0644]
common-src/versuff.c.in [new file with mode: 0644]
common-src/waitpid.c [new file with mode: 0644]
config/Makefile.am [new file with mode: 0644]
config/Makefile.in [new file with mode: 0644]
config/acinclude.m4i [new file with mode: 0644]
config/config.guess [new file with mode: 0755]
config/config.h.in [new file with mode: 0644]
config/config.sub [new file with mode: 0755]
config/depcomp [new file with mode: 0755]
config/install-sh [new file with mode: 0755]
config/libtool.m4i [new file with mode: 0644]
config/ltmain.sh [new file with mode: 0644]
config/missing [new file with mode: 0755]
config/mkinstalldirs [new file with mode: 0755]
configure [new file with mode: 0755]
configure.in [new file with mode: 0644]
contrib/README [new file with mode: 0644]
contrib/dbbackup.README [new file with mode: 0755]
contrib/dbbackup.ksh [new file with mode: 0755]
contrib/dbbackup.sql [new file with mode: 0755]
contrib/dbbackup.tcl [new file with mode: 0755]
contrib/mkamandisk [new file with mode: 0644]
contrib/set_prod_link.pl [new file with mode: 0644]
contrib/sst/Makefile [new file with mode: 0644]
contrib/sst/README [new file with mode: 0644]
contrib/sst/README.Amanda [new file with mode: 0644]
contrib/sst/sst.c [new file with mode: 0644]
contrib/sst/sst.conf [new file with mode: 0644]
contrib/sst/sst_def.h [new file with mode: 0644]
contrib/sst/sstest.c [new file with mode: 0644]
docs/DUMPER-API [new file with mode: 0644]
docs/EXCLUDE [new file with mode: 0644]
docs/FAQ [new file with mode: 0644]
docs/HOWTO-AFS [new file with mode: 0644]
docs/HOWTO-CYGWIN.html [new file with mode: 0644]
docs/HOWTO-FILE-DRIVER [new file with mode: 0644]
docs/INDEXING [new file with mode: 0644]
docs/INSTALL [new file with mode: 0644]
docs/INTERNALS [new file with mode: 0644]
docs/KERBEROS [new file with mode: 0644]
docs/LABEL.PRINTING [new file with mode: 0644]
docs/MULTITAPE [new file with mode: 0644]
docs/Makefile.am [new file with mode: 0644]
docs/Makefile.in [new file with mode: 0644]
docs/PORT.USAGE [new file with mode: 0644]
docs/RAIT [new file with mode: 0644]
docs/RESTORE [new file with mode: 0644]
docs/SAMBA [new file with mode: 0644]
docs/SECURITY [new file with mode: 0644]
docs/SYSTEM.NOTES [new file with mode: 0644]
docs/TAPE.CHANGERS [new file with mode: 0644]
docs/TAPETYPES [new file with mode: 0644]
docs/UPGRADE [new file with mode: 0644]
docs/VTAPE-API [new file with mode: 0644]
docs/WHATS.NEW [new file with mode: 0644]
docs/WISHLIST [new file with mode: 0644]
docs/YEAR2000 [new file with mode: 0644]
docs/ZFTAPE [new file with mode: 0644]
docs/chg-scsi.notes [new file with mode: 0644]
example/3hole.ps [new file with mode: 0644]
example/8.5x11.ps [new file with mode: 0644]
example/DIN-A4.ps [new file with mode: 0644]
example/DLT.ps [new file with mode: 0644]
example/EXB-8500.ps [new file with mode: 0644]
example/HP-DAT.ps [new file with mode: 0644]
example/Makefile.am [new file with mode: 0644]
example/Makefile.in [new file with mode: 0644]
example/amanda.conf.chg-scsi.in [new file with mode: 0644]
example/amanda.conf.in [new file with mode: 0644]
example/chg-mcutil.conf [new file with mode: 0644]
example/chg-mcutil.conf.in [new file with mode: 0644]
example/chg-multi.conf [new file with mode: 0644]
example/chg-scsi-hpux.conf.in [new file with mode: 0644]
example/chg-scsi-linux.conf.in [new file with mode: 0644]
example/chg-scsi-solaris.conf.in [new file with mode: 0644]
example/chg-scsi.conf [new file with mode: 0644]
example/config.site [new file with mode: 0644]
example/disklist [new file with mode: 0644]
man/Makefile.am [new file with mode: 0644]
man/Makefile.in [new file with mode: 0644]
man/amadmin.8.in [new file with mode: 0644]
man/amanda.8.in [new file with mode: 0644]
man/amcheck.8.in [new file with mode: 0644]
man/amcheckdb.8.in [new file with mode: 0644]
man/amcleanup.8.in [new file with mode: 0644]
man/amdd.8 [new file with mode: 0644]
man/amdump.8.in [new file with mode: 0644]
man/amflush.8.in [new file with mode: 0644]
man/amgetconf.8.in [new file with mode: 0644]
man/amlabel.8.in [new file with mode: 0644]
man/ammt.8 [new file with mode: 0644]
man/amoverview.8.in [new file with mode: 0644]
man/amplot.8 [new file with mode: 0644]
man/amrecover.8.in [new file with mode: 0644]
man/amreport.8.in [new file with mode: 0644]
man/amrestore.8 [new file with mode: 0644]
man/amrmtape.8.in [new file with mode: 0644]
man/amstatus.8.in [new file with mode: 0644]
man/amtape.8 [new file with mode: 0644]
man/amtapetype.8.in [new file with mode: 0644]
man/amtoc.8.in [new file with mode: 0644]
man/amverify.8.in [new file with mode: 0644]
man/amverifyrun.8.in [new file with mode: 0644]
patches/regex-3.6alpha.patch [new file with mode: 0644]
patches/samba-largefs.patch [new file with mode: 0644]
patches/tar-1.12.patch [new file with mode: 0644]
recover-src/Makefile.am [new file with mode: 0644]
recover-src/Makefile.in [new file with mode: 0644]
recover-src/amrecover.c [new file with mode: 0644]
recover-src/amrecover.h [new file with mode: 0644]
recover-src/display_commands.c [new file with mode: 0644]
recover-src/extract_list.c [new file with mode: 0644]
recover-src/help.c [new file with mode: 0644]
recover-src/set_commands.c [new file with mode: 0644]
recover-src/uparse.c [new file with mode: 0644]
recover-src/uparse.h [new file with mode: 0644]
recover-src/uparse.y [new file with mode: 0644]
recover-src/uscan.c [new file with mode: 0644]
recover-src/uscan.l [new file with mode: 0644]
regex-src/COPYRIGHT [new file with mode: 0644]
regex-src/Makefile [new file with mode: 0644]
regex-src/README [new file with mode: 0644]
regex-src/WHATSNEW [new file with mode: 0644]
regex-src/cclass.h [new file with mode: 0644]
regex-src/cname.h [new file with mode: 0644]
regex-src/debug.c [new file with mode: 0644]
regex-src/engine.c [new file with mode: 0644]
regex-src/fake/limits.h [new file with mode: 0644]
regex-src/fake/memmove.c [new file with mode: 0644]
regex-src/fake/stdlib.h [new file with mode: 0644]
regex-src/main.c [new file with mode: 0644]
regex-src/mkh [new file with mode: 0644]
regex-src/regcomp.c [new file with mode: 0644]
regex-src/regerror.c [new file with mode: 0644]
regex-src/regex.3 [new file with mode: 0644]
regex-src/regex.7 [new file with mode: 0644]
regex-src/regex2.h [new file with mode: 0644]
regex-src/regexec.c [new file with mode: 0644]
regex-src/regfree.c [new file with mode: 0644]
regex-src/split.c [new file with mode: 0644]
regex-src/tests [new file with mode: 0644]
regex-src/utils.h [new file with mode: 0644]
restore-src/Makefile.am [new file with mode: 0644]
restore-src/Makefile.in [new file with mode: 0644]
restore-src/amidxtaped.c [new file with mode: 0644]
restore-src/amrestore.c [new file with mode: 0644]
server-src/Makefile.am [new file with mode: 0644]
server-src/Makefile.in [new file with mode: 0644]
server-src/amadmin.c [new file with mode: 0644]
server-src/amcheck.c [new file with mode: 0644]
server-src/amcheckdb.sh.in [new file with mode: 0644]
server-src/amcleanup.sh.in [new file with mode: 0644]
server-src/amcleanupdisk.c [new file with mode: 0644]
server-src/amdump.sh.in [new file with mode: 0644]
server-src/amflush.c [new file with mode: 0644]
server-src/amfreetapes.sh.in [new file with mode: 0644]
server-src/amindex.c [new file with mode: 0644]
server-src/amindex.h [new file with mode: 0644]
server-src/amindexd.c [new file with mode: 0644]
server-src/amlabel.c [new file with mode: 0644]
server-src/amlogroll.c [new file with mode: 0644]
server-src/amoverview.pl.in [new file with mode: 0644]
server-src/amrmtape.sh.in [new file with mode: 0644]
server-src/amstatus.pl.in [new file with mode: 0644]
server-src/amtape.c [new file with mode: 0644]
server-src/amtoc.pl.in [new file with mode: 0644]
server-src/amtrmidx.c [new file with mode: 0644]
server-src/amtrmlog.c [new file with mode: 0644]
server-src/amverify.sh.in [new file with mode: 0644]
server-src/amverifyrun.sh.in [new file with mode: 0644]
server-src/changer.c [new file with mode: 0644]
server-src/changer.h [new file with mode: 0644]
server-src/conffile.c [new file with mode: 0644]
server-src/conffile.h [new file with mode: 0644]
server-src/disk_history.c [new file with mode: 0644]
server-src/disk_history.h [new file with mode: 0644]
server-src/diskfile.c [new file with mode: 0644]
server-src/diskfile.h [new file with mode: 0644]
server-src/driver.c [new file with mode: 0644]
server-src/driverio.c [new file with mode: 0644]
server-src/driverio.h [new file with mode: 0644]
server-src/dumper-krb4.c [new file with mode: 0644]
server-src/dumper.c [new file with mode: 0644]
server-src/find.c [new file with mode: 0644]
server-src/find.h [new file with mode: 0644]
server-src/getconf.c [new file with mode: 0644]
server-src/holding.c [new file with mode: 0644]
server-src/holding.h [new file with mode: 0644]
server-src/infofile.c [new file with mode: 0644]
server-src/infofile.h [new file with mode: 0644]
server-src/list_dir.c [new file with mode: 0644]
server-src/list_dir.h [new file with mode: 0644]
server-src/logfile.c [new file with mode: 0644]
server-src/logfile.h [new file with mode: 0644]
server-src/planner.c [new file with mode: 0644]
server-src/reporter.c [new file with mode: 0644]
server-src/server_util.c [new file with mode: 0644]
server-src/server_util.h [new file with mode: 0644]
server-src/tapefile.c [new file with mode: 0644]
server-src/tapefile.h [new file with mode: 0644]
server-src/taper.c [new file with mode: 0644]
tape-src/Makefile.am [new file with mode: 0644]
tape-src/Makefile.in [new file with mode: 0644]
tape-src/amdd.c [new file with mode: 0644]
tape-src/ammt.c [new file with mode: 0644]
tape-src/output-file.c [new file with mode: 0644]
tape-src/output-file.h [new file with mode: 0644]
tape-src/output-null.c [new file with mode: 0644]
tape-src/output-null.h [new file with mode: 0644]
tape-src/output-rait.c [new file with mode: 0644]
tape-src/output-rait.h [new file with mode: 0644]
tape-src/output-tape.c [new file with mode: 0644]
tape-src/output-tape.h [new file with mode: 0644]
tape-src/tapeio.c [new file with mode: 0644]
tape-src/tapeio.h [new file with mode: 0644]
tape-src/tapetype.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..8c8dd4b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,48 @@
+This file lists the current members of the Amanda Development Team,
+i.e., people who have write access to the sources of Amanda.
+
+Please avoid sending e-mail with Amanda-related questions directly to
+them; your questions are likely to be answered much faster if you post
+them to the Amanda Users mailing list: amanda-users@amanda.org
+
+
+- James da Silva <jds@cs.umd.edu>: Hacker Emeritus
+
+- Mike Grupenhoff <kashmir@munge.com>: ex-UMIACS hacker
+
+- Todd Kover <kovert@omniscient.com>: lists & ex-UMIACS hacker, active developer and
+supporter
+
+- James Mathiesen <James-Mathiesen@deshaw.com>: numerous bug fixes
+
+- Alan McIvor <a.mcivor@irl.cri.nz>: original developer of amindex
+feature, various bug fixes
+
+- George Scott <George.Scott@cc.monash.edu.au>: active developer and
+supporter in the 2.4.0 release cycle
+
+- Alexandre Oliva <oliva@lsd.ic.unicamp.br>: active developer and
+supporter
+
+- Blair Zajac <blair@gps.caltech.edu>: de-facto maintainer between
+release 2.3.0 and the creation of the Amanda Development Team, at some
+point after release 2.3.0.4.
+
+- Curtis Varner <cvarner@cs.ucr.edu>: planned features, bug fixes
+
+- John R. Jackson <jrj@gandalf.cc.purdue.edu>: security fixes, active
+developer and supporter
+
+- Jean-Louis Martineau <martinea@iro.umontreal.ca>: active developer
+and supporter
+
+- Thomas Hepper <th@ant.han.de>: active developer of changer-src
+
+- Jon LaBadie <jon@jgcomp.com>: active supporter
+
+- Stefan G. Weichinger <monitor@oops.co.at>: documentation, author of
+        file:driver
+
+
+Many other people have contributed to the development of Amanda; check
+the ChangeLog for their names and e-mail addresses.
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644 (file)
index 0000000..cea671e
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
diff --git a/COPYRIGHT-APACHE b/COPYRIGHT-APACHE
new file mode 100644 (file)
index 0000000..998fb56
--- /dev/null
@@ -0,0 +1,57 @@
+If your system does not have the snprintf function, then a version from
+the Apache distribution is used and has the following notice:
+
+/* ====================================================================
+ * Copyright (c) 1995-1997 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ * This code is based on, and used with the permission of, the
+ * SIO stdio-replacement strx_* functions by Panos Tsirigotis
+ * <panos@alumni.cs.colorado.edu> for xinetd.
+ */
diff --git a/COPYRIGHT-REGEX b/COPYRIGHT-REGEX
new file mode 100644 (file)
index 0000000..33743d3
--- /dev/null
@@ -0,0 +1,11 @@
+The regular expressions library used by Amanda was written by Henry
+Spencer.  The full library distribution is in the regex-src directory,
+as well as its copyright notice and license.
+
+A newer version of this library may be available in the URL
+ftp://ftp.zoo.toronto.edu/pub/regex.shar
+
+The one distributed with amanda since 2.4.0b4 is a slightly modified
+alpha3.6, released on September 30, 1997.  The differences between the
+released library and the one distributed with Amanda can be found in
+patches/regex-3.6alpha.patch
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..95f93e7
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,9900 @@
+2004-06-22  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * Amanda 2.4.4p3 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.4p3).
+       * News: Changes in release 2.4.4p3.
+
+2004-05-10  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/planner.c: Log L_DISK for autoflush disk.
+
+2004-04-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * common-src/amanda.h: #include "amanda-int.h" only if !CONFIGURE_TEST.
+
+2004-04-29  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * config/acinclude.m4i (AX_CREATE_STDINT_H) : New macro.
+       * configure.in: Use AX_CREATE_STDINT_H(common-src/amanda-int.h).
+       * common-src/amanda.h: include "common-src/amanda-int.h".
+       * changer-src/scsi-cam.c: Change u_int32_t for uint32_t.
+       * client-src/amandad-krb4.c: Change u_int32_t for uint32_t.
+       * common-src/krb4-security.c: Change u_int32_t for uint32_t.
+       * common-src/krb4-security.h: Change u_int32_t for uint32_t.
+       * common-src/protocol.h: Change u_int32_t for uint32_t.
+       * common-src/security.c: Change u_int32_t for uint32_t.
+
+2004-04-27  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: Fix for automake 1.8.4.
+       * config/acinclude.m4i: Fix for automake 1.8.4.
+
+2004-04-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: Result of autoupdate.
+
+2004-04-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * config/config.guess: Update from automake 1.8.
+       * config/config.sub: Update from automake 1.8.
+       * config/depcomp: Update from automake 1.8.
+       * config/install-sh: Update from automake 1.8.
+       * config/missing: Update from automake 1.8.
+       * config/mkinstalldirs: Update from automake 1.8.
+       * config/ltmain.sh: Update from libtool-1.5.6.
+       * config/libtool.m4i: Update from libtool-1.5.6.
+
+2004-04-26  Marc Mengel <mengel@fnal.gov>
+
+       * tape-src/output-rait.c: Verify reads correctly.
+
+2004-04-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/driver.c (continue_dumps): Fix deadlock if holding disk
+         fill up when in degraded mode.
+
+2004-04-23  Eric Siegerman <eric_97@pobox.com>
+
+       Bug fix: amflush would run, and consume a tape, even if there
+       were no Amanda directories waiting to be flushed:
+       * common-src/sl.c (is_empty_sl): New function to test
+         whether a list is empty.
+       * common-src/sl.h (is_empty_sl): Prototype.
+       * server-src/amflush.sh (main): Use is_empty_sl(),
+         rather than ==NULL, to test emptiness of datestamp_list.
+
+2004-04-23  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/planner.c (setup_estimate): Typo.
+
+2004-04-22  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Fix by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/planner.c (setup_estimate): Only ask for level 0 estimate
+         if strategy is noinc.
+
+2004-04-21  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Documentation from Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * man/amoverview.8.in: Document results.
+
+2004-04-21  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/amoverview.pl.in: Print last two characters.
+
+2004-04-16  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/chg-disk.sh.in: Fix for sh compatibility.
+
+2004-04-14  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Fix by John Koyle <jkoyle@rfpdepot.com>
+
+       * common-src/protocol.c: Fix EAGAIN on Linux.
+
+2004-03-16  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amcheck.c: Do labelstr check in correct order.
+
+2004-02-13  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Reported by Allen Liu <allen@bellglobal.com>
+
+       * server-src/amverifyrun.sh.in: Replace '-e' test by '-f'.
+
+2004-02-13  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amcheck.c: Verify the tape is listed in the tapelist file.
+       * server-src/taper.c: Ditto
+       * NEWS: * amanda will not use a tape if it's label is not in the
+                 tapelist file (eg. after an amrmtape).
+
+2004-02-12  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Philippe Charnier <charnier@xp11.frmug.org>
+
+       * server-src/amtrmidx.c: Add '\n'.
+
+2004-02-11  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * recover-src/set_commands.c (cd_glob): Fix memory leak.
+
+2004-02-11  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * recover-src/set_commands.c (cd_dir, set_directory): Fix memory leak.
+       * recover-src/uscan.l: Fix double amfree.
+
+2004-01-29  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * Makefile.am (EXTRA_DIST): Add contrib/mkamandisk.
+
+2004-01-29  Christoph Pospiech <pospiech@de.ibm.com>
+
+        * configure.in (AC_CONFIG_FILES): Add changer-src/chg-iomega.pl.
+        * changer-src/Makefile.am (libexec_SCRIPTS) Add chg-iomega.
+        * changer-src/chg-iomega.pl.in: New changer script.
+        * docs/TAPE.CHANGERS: Document chg-iomega.
+       * contrib/mkamandisk: Script to format iomega disk.
+       * NEWS: New chg-iomega changer script.
+
+2004-01-29  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * restore-src/amidxtaped.c (scan_init): Remove the log file if it exit.
+
+2004-01-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: Set GNUTAR_LISTED_INCREMENTAL_DIRX.
+       * example/amanda.conf.in: Update record documentation.
+       * man/amanda.8.in: Update record documentation.
+
+2004-01-13  Greg Troxel  <gdt@t...>
+
+       * common-src/krb4-security.c (errstr;): Make krb4 work on 64-bit
+         platforms.  Essentially, change 'unsigned long' to u_int32_t for
+         on-the-wire representation of checksums, declaring that the wire
+         protocol is defined by existing use of unsigned long on 32-bit
+         machines.
+
+         Modify the data/control handshake similarly, defining a
+         'net_timeval' that uses int32_t rather than long.  Cleanup a latent
+         bug in handshake code that didn't cause trouble before when
+         everything was the same type.
+
+         This change preserves interoperability with the previous code
+         on 32 bit machines.  (It is likely that 64/64 interoperability
+         was ok, but unlikely that it was important to anyone, given
+         the low population of amanda-krb users.)
+
+2004-01-14  Stefan G. Weichinger <monitor@oops.co.at>
+
+       * docs/INSTALL: Add config for xinetd.
+
+2004-01-08  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * Amanda 2.4.4p2 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.4p2).
+
+
+2004-01-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/planner.c (handle_result): Detect bad estimate (-1).
+       * server-src/planner.c (analyze_estimate): Don't schedule level
+         if the estimate is bad.
+
+2003-12-19  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * client-src/Makefile.am (EXTRA_DIST): Add amandad-krb4.c,
+         sendbackup-krb4.c and sendbackup-krb4.h.
+       * common-src/Makefile.am (EXTRA_DIST): Add krb4-security.c and
+         krb4-security.h.
+       * server-src/Makefile.am (EXTRA_DIST): Add dumper-krb4.c.
+       * NEWS: Kerberos 4 support integrated and functional again.
+
+2003-12-16  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       patch by Greg Troxel <gdt@ir.bbn.com>
+             and Beverly Schwartz <bschwart@bbn.com>
+
+       Original *krb4* files are taken form the amanda-krb repository.
+
+       Add kerberos 4 support.
+       * client-src/amandad-krb4.c: New file.
+       * client-src/amandad.c: Fix close of req_pipe[0]/rep_pipe[1].
+       * client-src/sendbackup-krb4.c: New file.
+       * client-src/sendbackup-krb4.h: New file.
+       * client-src/sendbackup.c: Use options->krb4_auth.
+       * common-src/amanda.h: Fix for initgroups.
+       * common-src/krb4-security.c: New file.
+       * common-src/krb4-security.h: New file.
+       * common-src/token.h: Use HAVE_SHQUOTE_DECL.
+       * configure.in: Enhance finding krb libs.
+       * server-src/diskfile.c: Fix.
+       * server-src/dumper-krb4.c: New file.
+       * server-src/getconf.c: Define HOSTNAME_INSTANCE.
+
+2003-12-16  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * docs/HOWTO-FILE-DRIVER: New file.
+       * docs/TAPE.CHANGERS: Explain chg-disk.
+       * docs/Makefile.am (pkgdata_DATA): add HOWTO-FILE-DRIVER.
+
+2003-12-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * docs/SYSTEM.NOTES: Add a note about sendsize coredump on AIX.
+
+2003-11-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Jean-Christian SIMONETTI <simonetti@echo.fr>
+
+       * changer-src/chg-disk.sh.in: New changer script.
+       * changer-src/Makefile.am (libexec_SCRIPTS): Add chg-disk.
+       * configure.in (AC_CONFIG_FILES): Add changer-src/chg-disk.sh.
+       * NEWS: new chag-disk changer script to use with the file: driver.
+
+2003-11-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/tapetype.c: extern int optind.
+       * tape-src/tapeio.c: extern int optind.
+
+2003-11-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by C.Scheeder <christoph.scheeder@scheeder.de
+
+       * changer-src/sense.c (SenseType): Add "DAT AutoChanger" and "C1537A".
+
+2003-11-27  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/driver.c: Print the tape size.
+       * server-src/amstatus.pl.in: print % of tape use.
+
+2003-11-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/conffile.c (copy_dumptype): Copy in/exclude only if seen.
+
+2003-11-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/reporter.c (output_tapeinfo): Fix printing of new tape.
+
+2003-11-25  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amcheck.c (taperscan_slot): Deal with label not in
+         tapelist case.
+       * server-src/amtape.c (taperscan_slot): Ditto.
+       * server-src/taper.c (taperscan_slot): Ditto.
+
+2003-11-24  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/driver.c (handle_taper_result): Empty tapeq in TAPE_ERROR
+         and BOGUS case.
+
+2003-11-24  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/driver.c (handle_taper_result): Always call
+         continue_dumps() in TRYAGAIN case.
+
+2003-11-21  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/chg-chio.pl.in (getTapeStatus): Set $drives[$num] to 0
+       if no tape in drive.
+
+2003-11-20  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * docs/Makefile.am (pkgdata_DATA): Add HOWTO-AFS.
+
+2003-11-18  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Mitch Collinsworth <mitch@ccmr.cornell.edu>
+
+       * client-src/selfcheck.c: Skip accessibility check for AFS entries.
+       * docs/HOWTO-AFS: New file.
+
+2003-11-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amadmin.c (tape): Display the next new tapes.
+       * server-src/reporter.c (output_tapeinfo): Ditto.
+
+2003-10-31  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * docs/Makefile.am (pkgdata_DATA): Add chg-scsi.notes.
+
+2003-10-31  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amcheck.c (taperscan_slot): Set found=3 if new tape.
+       * server-src/amcheck.c (taper_scan): Handle found==3.
+       * server-src/amtape.c (taperscan_slot): Set found=3 if new tape.
+       * server-src/amtape.c (taper_scan): Handle found==3.
+       * server-src/taper.c (taperscan_slot): Set found=3 if new tape.
+       * server-src/taper.c (taper_scan): Handle found==3.
+
+2003-10-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amcheck.c: Use stralloc(optarg).
+       * tape-src/ammt.c: Use stralloc(optarg).
+       * tape-src/tapetype.c: Use stralloc(optarg).
+
+2003-10-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Jay Fenlason <fenlason@redhat.com>
+
+       * server-src/dumper.c: Don't set SIGCHLD to SIG_IGN.
+
+2003-10-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Andrew Rucker Jones <arjones@simultan.dyndns.org>
+
+       * client-src/sendbackup-gnutar.c (AM_SIZE_RE): Fix regex for samba3.
+
+2003-10-27  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amadmin.c (find): Call find_dump to allow dynamic disklist.
+       * server-src/amindexd.c: Call find_dump to allow dynamic disklist.
+       * server-src/amtrmidx.c:  Call find_dump to allow dynamic disklist.
+       * server-src/diskfile.c (add_disk): Set device and todo.
+       * server-src/find.c: Build disklist dynamicaly from log files.
+       * server-src/find.h (find_dump): New prototype.
+       * NEWS: 'amadmin find' list disk removed from the disklist.
+       * NEWS: amrecover can recover a disk removed from the disklist file.
+
+2003-10-27  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amlogroll.c: set_pname("amlogroll").
+
+2003-10-24  Todd M. Kover <kovert@omniscient.com>
+
+       * add amqde for "quick and dirty estimates" under gnutar (program
+         that will traverse the filesystem rather than invoke gnutar).
+         controlled via configure option --with-qde.  This really wants to
+         be configured in the server.
+
+2003-10-24  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amverify.sh.in: Fix usage message.
+       * common-src/fileheader.c (print_header): fprintf to outf.
+       * server-src/tapefile.c (lookup_last_reusable_tape): Check for
+         tp->datestamp > 0.
+       * server-src/amadmin.c (disklist_one): Don't print ':' on device line.
+
+2003-10-22  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * client-src/amandates.c (finish_amandates): Call error() if the
+         close of amdf fail.
+       * common-src/amflock.c (create_lock): Return -1 if the close of f fail.
+       * common-src/amflock.c (read_lock): Don't set f to NULL if the close
+         fail.
+       * server-src/tapefile.c (write_tapelist): Return 1 if the close of
+         tapef fail.
+
+2003-10-14  John R. Jackson (jrj@purdue.edu)
+
+       * docs/SYSTEM.NOTES: Add FreeBSD 5.1 note about setting the UDP packet
+         size, compliments of Nicolas Ecarnot <nicolas.ecarnot@accim.com>.
+
+2003-10-14  John R. Jackson (jrj@purdue.edu)
+
+       * client-src/sendsize.c: Handle case where PID's get re-used.
+
+2003-10-14  John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Need to check for sys/gscdds.h on AIX to enable
+         SCSI changer.
+
+2003-10-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * common-src/genversion.c (prundefvar): New macro to print an
+         undefined variable.
+       * common-src/genversion.c: Print undefined variable.
+       * server-src/amcheck.c: Improve message for no LPRCMD defined.
+
+2003-07-08  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * restore-src/amidxtaped.c: Don't clear re_label before checking
+         for the changer.
+
+2003-07-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Scott Mcdermott <smcdermott@questra.com>
+
+       * changer-src/chg-zd-mtx.sh.in (initial_poll_delay): New config
+         variable to add a pause after a tape loading.
+       * News: New initial_poll_delay config in chg-zd-mtx.
+
+2003-07-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Fix by John E. Hein <jhein@timing.com>
+
+       * changer-src/chg-manual.sh.in: Quote @EGREP@.
+       * changer-src/chg-null.sh.in: Quote @EGREP@.
+
+2003-07-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * amplot/amplot.sh.in: Remove files before runnig amplot.awk.
+       * amplot/amplot.awk: Parse 'flush line', fix tape_wait line.
+       * server-src/driver.c (read_flush): Write a 'flush size' to the
+         debug file.
+
+2003-07-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/chg-chio.pl.in: Fix next/prev command.
+
+2003-07-06  Thomas Hepper <th@ant.han.de>
+       * changer-src/chg-scsi.c: Added debug Information to see which sg
+        version is used
+       * changer-src/scsi-linux.c: Added debug Information to see which sg
+       version is used.
+       Removed check if an data packet is larger than 4096 byte.
+
+2003-07-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * client-src/client_util.c (add_include): Count include with 2 /,
+         Fix descriptor leak.
+
+2003-06-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.4p1 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.4p1).
+
+
+2003-06-25  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amstatus.pl.in: Fix print spacing for idle dumpers.
+
+2003-06-20  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * tape-src/tapetype.c: Avoid a numerical overflow for large tape
+         capacities.
+
+2003-06-20  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amstatus.pl.in: Fix to failed tape.
+
+2003-06-18  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/planner.c (delay_dumps): Delay not delay forced full
+         before forced full.
+
+2003-06-18  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/chg-zd-mtx.sh.in: Log the changer file used.
+
+2003-06-14  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/holding.c: Skip lost+found directories on holding disks.
+
+2003-06-11  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amverify.sh.in: Do not advance to next tape.
+
+2003-06-10  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       patch by Eric Siegerman <eric_97@pobox.com>
+
+       * server-src/planner.c: Make promote_hills() honour maxpromotedays.
+
+2003-06-05  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/scsi-bsd.c: Use pDev[DeviceFD].fd instead of DeviceFD.
+       * changer-src/scsi-hpux_new.c:Use pDev[DeviceFD].fd instead of DeviceFD.
+       * changer-src/scsi-linux.c: Use pDev[ip].fd instead of DeviceFD.
+
+2003-06-05  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amflush.c: Implement new -b and -s options.
+       * man/amflush.8.in: Document it.
+
+2003-06-05  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/driver.c (dump_to_tape): Don't go in degraded mode if
+         taper reply DONE.
+
+2003-06-05  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/output-rait.c: Don't call waitpid if we didn't fork.
+
+2003-06-04  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amverify.sh.in: Use @MAXTAPEBLOCKSIZE@ instead of 32.
+
+2003-06-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Bug reported by Sven Rudolph <rudsve@drewag.de>
+
+       * server-src/holding.c (mkholdingdir): New function to create a holding
+         directory.
+       * server-src/holding.h (mkholdingdir): Prototype.
+       * server-src/driver.c: Use mkholdingdir;
+       * server-src/dumper.c: Call mkholdingdir before opening a file for
+         writing.
+
+2003-06-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/amstatus.pl.in: Fix for missing amdump.1 or amflush.1.
+
+2003-06-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/amstatus.pl.in: If nothing is active, it now gives the
+         status of the last run (amdump or amflush).
+       * man/amstatus.8.in: Document it.
+
+2003-05-29  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/output-file.c (check_online): Write error if opendir failed.
+
+2003-05-29  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/amoverview.pl.in: Use 'amadmin <conf> disklist' instead
+         of parsing the disklist file.
+
+2003-05-27  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/tapefile.c (read_tapelist,parse_tapeline): Fix for
+         previous patch.
+
+2003-05-16  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * example/amanda.conf.in: Add more amrecover_changer doc.
+       * man/amanda.8.in: Add more amrecover_changer doc.
+       * man/amrecover.8.in: Add more amrecover_changer doc.
+
+2003-05-12  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/tapefile.c (read_tapelist): Ignore blank line.
+       * server-src/tapefile.c (parse_tapeline): Newer status parameter, set
+         it to '1' when reading blank line.
+
+2003-04-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in (AC_CHECK_HEADERS): Remove linux/ftape-header-segment.h,
+         linux/ftape-vendors.h and linux/ftape.h.
+
+2003-04-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Darin Dugan <dddugan@iastate.edu>
+
+       * server-src/amcheck.c: Change subject in email if no error.
+
+2003-04-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * common-src/error.c (output_error_message): Always prepend program
+         name.
+       * server-src/dumper.c (process_dumpeof): 'missing size line' and
+         'missing end line' should be failed, not strange.
+
+2003-04-15  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amstatus.pl.in: Fix for estimate disk.
+
+2003-04-14  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/taper.c: Read holding file correctly if blocksize != 32k.
+
+2003-04-13  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       New file by Robert C Dege <RDege@northropgrumman.com>
+
+       * configure.in: Find mcutil binary.
+       * configure.in (AC_CONFIG_FILES): Add changer-src/chg-mcutil.sh and
+         example/chg-mcutil.conf.
+       * changer-src/Makefile (libexec_SCRIPTS): Add chg-mcutil.
+       * changer-src/chg-mcutil.sh.in: New file.
+       * example/Makefile (EXTRA_DIST): Add chg-mcutil.conf
+       * example/chg-mcutil.conf.in: New file.
+
+2003-04-08  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * man/amanda.8.in (blocksize): Document the --with-maxtapeblocksize
+         configure option.
+
+2003-04-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amverifyrun.sh.in: Run the amverify command.
+
+2003-04-01  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/reporter.c: Get the filenumber correct.
+
+2003-04-01  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * server-src/reporter.c: Print a postscript label for each tape used.
+       * NEWS: Print a postscript label for each tape used.
+
+2003-03-18  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in (*-sco3.2v4*): It is not like *-sco3.2v5*,
+         define DEV_PREFIX and RDEV_PREFIX.
+
+2003-03-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: Typo.
+
+2003-03-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Gert Doering <gert@greenie.muc.de>
+
+       * client-src/getfsent.c (get_fstab_nextentry): Compile on *-sco3.2v4*.
+
+2003-03-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: Compile on *-sco3.2v4*
+
+2003-03-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: Use '=' instead of '=='.
+
+2003-03-14  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * recover-src/set_commands.c (set_tape): Recognize null:, rait:, 
+         file: and tape: as driver, not host name.
+
+2003-03-14  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amrmtape.sh.in: Print better output.
+
+2003-03-13  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/Makefile.am (libexec_SCRIPTS): Missing \.
+
+2003-03-08  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * NEWS: amrecover_changer works with chg-multi.
+
+2003-03-08  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * client-src/client_util.c (add_include): If include contain 2 '/' then
+         use at asis, don't try to match it.
+
+2003-03-07  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * file tape-src/output-rait.c (rait_open): Call tapefd_set_master_fd();
+       * file tape-src/tapeio.c (struct tape_info): Add master_fd field.
+       * file tape-src/tapeio.c (tape_info_init): Set master_fd to -1;
+       * file tape-src/tapeio.c (tapefd_getinfo_host, tapefd_getinfo_disk, 
+         tapefd_getinfo_level): Return info of master_fd.
+       * file tape-src/tapeio.c (tapefd_set_master_fd): New function to set
+         master_fd.
+       * file tape-src/tapeio.h (tapefd_set_master_fd): Prototype.
+       * NEWS: rait: works with file:
+
+2003-03-06  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/output-file.c (file_tapefd_can_fork): New function that 
+         return 1 if the file: can be run under a forked process.
+       * tape-src/output-file.h (file_tapefd_can_fork): Prototype.
+       * tape-src/output-null.c (null_tapefd_can_fork): New function that 
+         return 1 if the null: can be run under a forked process.
+       * tape-src/output-null.h (null_tapefd_can_fork): Prototype.
+       * tape-src/output-rait.c (rait_close, rait_tapefd_ioctl): Fork only if
+       * tapefd_can_fork() return 1.
+       * tape-src/output-rait.c (rait_tapefd_can_fork): New function that 
+         return 1 if the rait: can be run under a forked process.
+       * tape-src/output-rait.h (rait_tapefd_can_fork): Prototype.
+       * tape-src/output-tape.c (tape_tapefd_can_fork): New function that 
+         return 1 if the tape: can be run under a forked process.
+       * tape-src/output-tape.h (tape_tapefd_can_fork): Prototype.
+       * tape-src/tapeio.c (struct virtualtape): Add xxx_tapefd_can_fork and
+         initialize vtable[];
+       * tape-src/tapeio.c (tapefd_can_fork): New function to can the driver 
+         xxx_tapefd_can_fork function.
+       * tape-src/tapeio.h (tapefd_can_fork): Prototype.
+
+2003-03-05  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/output-file.c (file_tapefd_write): Call file_release(fd)
+         before opening the file for writing.
+
+2003-03-04  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/chg-zd-mtx.sh.in: Default for driveslot is 0.
+       * NEWS: default driveslot for chg-zd-mtx is now 0.
+
+2003-03-04  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * amplot/amplot.sh.in: New -b option for b/w postscript.
+       * amplot/amplot.awk: Add 'color' to command if bw is set.
+       * amplot/amplot.g: Change line 6 to line 8.
+       * man/amplot.8: Document -b option.
+       * NEWS: Document amplot -b option.
+
+2003-03-04  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * recover-src/extract_list.c: Fix the name of the
+         amidxtaped.<timestamp>.debug file.
+
+2003-02-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Eric Doutreleau <Eric.Doutreleau@int-evry.fr>
+
+       * restore-src/amidxtaped.c: Use the device sent by the changer.
+
+2003-02-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * restore-src/amidxtaped.c: Remove lock 'unlink(conf_logfile)' on
+         all failure path.
+
+2003-02-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Martin Forssen <maf@appgate.com>
+
+       * server-src/changer.c (changer_label): Do not amfree(rest).
+
+2003-02-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.4 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.4).
+
+2003-02-21  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * client-src/client_util.c: Print error except ENOENT for 
+         exclude/include files.
+
+2003-02-20  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/tapetype.c: Use %ld to print some variable.
+
+2003-02-20  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/conffile.c (init_defaults): conf_printer.s must be set 
+         with stralloc("").
+
+2003-02-12  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * tape-src/tapetype.c: Document -c option.
+
+2003-02-12  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/chg-zd-mtx.sh.in:Print "are you sure your drive slot is n"
+
+2003-02-12  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/tapefile.c (read_tapelist): return 1 if can't open the 
+         tapelist file.
+
+2003-02-12  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * man/amtapetype.8.in: Add doc from a mail by John R. Jackson.
+
+2003-02-11  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amcheck.c: New -a option.
+       * man/amcheck.8.in: Document it.
+       * NEWS: Document it.
+
+2003-02-11  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amindexd.c (build_disk_table): Compare the level.
+
+2003-02-10  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+       * tape-src/tapetype.c: New -c argument to do only the compression test.
+         Better detection of compression.
+       * man/amtapetype.8.in: Document -c argument.
+
+2003-02-09  John R. Jackson (jrj@purdue.edu)
+
+       * tape-src/tapetype.c: Allocate the I/O buffers on page boundaries.
+         This helps performance on some OS's.
+
+2003-02-08  John R. Jackson (jrj@purdue.edu)
+
+       * restore-src/amrestore.c: Clean up strtol() argument processing.
+
+2003-02-08  John R. Jackson (jrj@purdue.edu)
+
+       * docs/INSTALL: Clean up supporting package versions and URL's.
+
+2003-02-06  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * docs/Makefile.am (pkgdata_DATA): Add HOWTO-CYGWIN.html.
+
+2003-02-04  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Christophe Kalt <kalt@taranis.org>
+
+       * client-src/sendbackup-dump.c: New AM_SIZE_RE for NetApp.
+       * client-src/sendsize.c: New re_size for NetApp.
+
+2003-02-04  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Fix by Colin Henein <cmh@orange-carb.org>
+
+       * common-src/amanda.h: Fix for the where S_ISDIR is not defined.
+
+2003-02-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Doug Kingston <dpk@randomnotes.org>
+
+       * configure.in (NEED_SETUID_CLIENT): Set to false on *-pc-cygwin.
+       * configure.in (WANT_SETUID_CLIENT): Set if NEED_SETUID_CLIENT != false.
+       * client-src/Makefile.am: Don't chmod u+s if WANT_SETUID_CLIENT.
+
+2003-02-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Andrew Rucker Jones <arjones@simultan.dyndns.org>
+
+       * man/amtapetype.8.in: Fix example.
+
+2003-01-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.4b1 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.4b1).
+
+2003-01-31  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * common-src/amanda.h: #define S_ISDIR if not already defined.
+
+2003-01-31  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       File from Doug Kingston <dpk@randomnotes.org>
+
+       * docs/HOWTO-CYGWIN.html: New file.
+
+2003-01-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: Define WANT_RUNTIME_PSEUDO_RELOC on cygwin
+       * client-src/Makefile.am: AM_LDFLAGS="-Wl,-enable-runtime-pseudo-reloc"
+         if WANT_RUNTIME_PSEUDO_RELOC.
+       * recover-src/Makefile.am: Ditto.
+
+2003-01-28  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/output-rait.h: #define stralloc strdup
+       * tape-src/output-rait.c: Revert patch of 2003-01-26, we don't have
+         vstralloc in standalone.
+
+2003-01-27  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Reported by Doug Kingston <dpk@randomnotes.org>
+
+       * recover-src/Makefile.am: Set AM_YFLAGS instead of YFLAGS.
+
+2003-01-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/output-rait.c (tapeio_next_devname): Use vstralloc.
+
+2003-01-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * changer-src/chg-scsi-chio.c: Change strdup to stralloc.
+       * changer-src/chg-scsi.c: Ditto.
+       * changer-src/scsi-aix.c: Ditto.
+       * changer-src/scsi-bsd.c: Ditto.
+       * changer-src/scsi-cam.c: Ditto.
+       * changer-src/scsi-changer-driver.c: Ditto.
+       * changer-src/scsi-hpux_new.c: Ditto.
+       * changer-src/scsi-irix.c: Ditto.
+       * changer-src/scsi-linux.c: Ditto.
+       * changer-src/scsi-solaris.c: Ditto.
+       * changer-src/sense.c: Ditto.
+       * tape-src/output-rait.c: Ditto.
+
+2003-01-26  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/taper.c (read_file): Don't count header in filesize.
+
+2003-01-25  John R. Jackson (jrj@purdue.edu)
+
+       * tape-src/tapeio.c: Fix tape_access() and tape_stat() problem caused
+         by indeterminate compiler order of evaluation.
+
+2003-01-25  John R. Jackson (jrj@purdue.edu)
+
+       * restore-src/amidxtaped.c: Log errno when tape_stat fails.
+       * restore-src/amrestore.c: Ditto.
+       * tape-src/output-rait.c: Ditto.
+
+2003-01-24  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amstatus.pl.in: print an usage by tape.
+
+2003-01-23  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * recover-src/extract_list.c (add_extract_item, delete_extract_item): 
+         Check also for level when comparing label.
+
+2003-01-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/dumper.c (update_dataptr): Loop if rc == 0.
+
+2003-01-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       Do not build chg-scsi-chio, it is buggy.
+       * changer-src/Makefile.am (libexec_PROGRAMS): remove $(CHIO_SCSI).
+       * changer-src/Makefile.am (EXTRA_PROGRAMS): add $(CHIO_SCSI).
+
+2003-01-16  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * configure.in: disable amrestore if --without-server is set.
+
+2003-01-04  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * client-src/amandad.c: Use the dbfd macro instead of the external
+         variable db_fd.
+       * client-src/selfcheck.c: Ditto.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * client-src/sendbackup-gnutar.c: Use save_errno instead of errno.
+       * common-src/debug.c: Move most declaration inside #ifdef DEBUG_CODE.
+       * server-src/amindexd.c: dup db_fd() to stderr.
+       * server-src/conffile.c: Don't call error() if the config file does not
+         exist, just write to stderr and set got_parserror.
+
+2003-01-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * recover-src/amrecover.c: Fix memory leak.
+
+2003-01-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       Add new maxpromoteday option in a dumptype.
+       * NEWS: Document it.
+       * example/amanda.conf.in: Give an example
+       * man/amanda.8.in: Document it.
+       * server-src/amadmin.c: Print it in the disklist subcommand.
+       * server-src/conffile.c: read it.
+       * server-src/conffile.h (dumptype_t): Add maxpromoteday and
+         s_maxpromoteday.
+       * server-src/diskfile.c (read_diskline): Copy maxpromoteday from
+         dumptype_t to disk_t.
+       * server-src/diskfile.h (disk_t):  Add maxpromoteday.
+       * server-src/planner.c (promote_highest_priority_incr): Don't promote
+         a disk if est(dp)->next_level0 > dp->maxpromoteday.
+
+2003-01-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Reported by Josh More <jmore@remote-print.com>
+
+       * client-src/client_util.c (add_exclude, add_include): Remove the
+         need for MAXPATHLEN.
+
+2003-01-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Fix by Josh More <jmore@remote-print.com>
+
+       * tape-src/output-tape.c: Add a ; after f = MT_UNLOAD
+
+2003-01-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amcheck.c (handle_response): Print 'request timed out' or
+         'reply timed out'.
+       * server-src/dumper.c (sendbackup_response): Print 'request timeout' or
+         'reply timeout'.
+
+2003-01-02  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * common-src/protocol.h (proto_t): Add prevstate field.
+       * common-src/protocol.c: Keep prevstate up to date.
+       * server-src/planner.c (handle_result): Use prevstate to write
+         Request or Estimate timeout.
+
+2003-01-01  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Undo patch of 2002-11-27. That doesn't work well for the planner.
+
+       * common-src/amanda.h (days_diff): Revert to old macro.
+       * server-src/amadmin.c: Undo Fix for newer days_diff.
+       * server-src/planner.c: Undo Fix for newer days_diff.
+
+2003-01-01  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * client-src/client_util.c: Fix memory leak reported by valgrind.
+       * client-src/selfcheck.c: Ditto.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * common-src/amfeatures.c: Ditto.
+       * common-src/debug.c: Ditto.
+       * common-src/file.c: Ditto.
+       * common-src/security.c: Ditto.
+       * recover-src/amrecover.c: Ditto.
+       * recover-src/extract_list.c: Ditto.
+       * recover-src/set_commands.c: Ditto.
+       * recover-src/uparse.y: Ditto.
+       * recover-src/uscan.l: Ditto.
+       * server-src/amcheck.c: Ditto.
+       * server-src/amindexd.c: Ditto.
+       * server-src/amlabel.c: Ditto.
+       * server-src/amlogroll.c: Ditto.
+       * server-src/amtape.c: Ditto.
+       * server-src/amtrmidx.c: Ditto.
+       * server-src/amtrmlog.c: Ditto.
+       * server-src/changer.c: Ditto.
+       * server-src/conffile.c: Ditto.
+       * server-src/diskfile.c: Ditto.
+       * server-src/driver.c: Ditto.
+       * server-src/driverio.c: Ditto.
+       * server-src/dumper.c: Ditto.
+       * server-src/find.c: Ditto.
+       * server-src/getconf.c: Ditto.
+       * server-src/holding.c: Ditto.
+       * server-src/logfile.c: Ditto.
+       * server-src/planner.c: Ditto.
+       * server-src/reporter.c: Ditto.
+       * server-src/tapefile.c: Ditto.
+       * server-src/taper.c: Ditto.
+
+2002-12-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * amplot/amplot.awk: Many fix.
+
+2002-12-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/planner.c (promote_highest_priority_incremental): Promote
+         a disk > balanced size if no full today. Do not promote a disk it's
+         the only disk due that day and no full today.
+
+2002-12-30  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+       Patch by Brad Roberts <braddr@puremagic.com>
+
+       * server-src/amflush.c: Remove 2 redundant amfree call after remove_sl.
+       * server-src/holding.c (get_flush): Ditto.
+
+2002-12-27  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/conffile.c: New taperalgo configuration keyword.
+       * server-src/conffile.h: Ditto.
+       * man/amanda.8.in: Document it.
+       * server-src/driver.c (startaflush): New function to start a flush to
+         tape.
+
+2002-12-23  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amstatus.pl.in: Parse features from PORT-WRITE line.
+
+2002-12-19  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       Don't use the G flag for samba backup restore by tar.
+       * recover-src/extract_list.c (enum dumptypes): Add IS_SAMBA_TAR.
+       * recover-src/extract_list.c (extract_files_child): Set dumptype to
+         IS_SAMBA_TAR if it's a SAMBA backup. Don't pass the G flag to tar
+         if it's IS_SAMBA_TAR.
+       
+2002-12-18  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * amplot/amplot.awk: Parse line with features, parse ENDFLUSH line.
+
+2002-12-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/planner.c (promote_highest_priority_incremental): Newer
+         algorithm that reduce the number of level 0 by hosts on a single day.
+
+2002-12-17  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * amplot/amplot.awk: Parse newer log lines.
+
+2002-12-12  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * client-src/selfcheck.c: Typo.
+
+2002-12-11  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/reporter.c (output_stats): Typo.
+
+2002-12-09  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/reporter.c: Print an usage by tape.
+
+2002-12-05  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/tapeio.c (do_read): Init count to 0.
+
+2002-12-05  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/Makefile.am: Install tapetype program as amtapetype.
+       * docs/TAPETYPES: Change for amtapetype.
+       * man/amtapetype.8.in: New man page
+       * man/Makefile.am: Install it.
+       * configure.in (AC_CONFIG_FILES): Add man/amtapetype.8.
+
+2002-12-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * tape-src/ammt.c (optind): Add prototype.
+       * tape-src/amdd.c (optind): Add prototype.
+
+2002-12-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * common-src/arglist.h (printf_arglist_function,
+         printf_arglist_function1, printf_arglist_function2): Define if
+         STDC_HEADERS is not defined.
+
+2002-12-03  Jean-Louis Martineau <martineau@iro.umontreal.ca>
+
+       * server-src/amstatus.pl.in: New --date option to display datestamp.
+       * server-src/amstatus.pl.in: Increase some field size.
+       * server-src/amstatus.pl.in: The host field adjust it's length to the
+        largest.
+
+2002-11-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amanda.h (days_diff): Don't add a half day.
+       * server-src/amadmin.c: Fix for newer days_diff.
+       * server-src/planner.c: Fix for newer days_diff.
+
+2002-11-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * tape-src/tapetype.c: Cast time_t to long for printing.
+
+2002-11-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amflush.c: Write a "amflush: start at ???" line.
+       * server-src/amstatus.pl.in: parse the "amflush: start at ???" line.
+
+2002-11-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (delay_dumps): Use ap_snprintf.
+
+2002-11-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/debug.c: Most of the code must in #ifdef DEBUG_CODE.
+       * client-src/client_util.c: Use AMANDA_TMPDIR instead of AMANDA_DBGDIR.
+
+2002-11-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/TAPE.CHANGERS: Sync with 2.5.0
+       * changer-src/chg-juke.sh.in: New changer from 2.5.0
+       * changer-src/chg-rait.sh.in: New changer from 2.5.0
+       * changer-src/chg-null.sh.in: New changer from 2.5.0
+       * changer-src/Makefile.am: Install them.
+       * configure.in (AC_CONFIG_FILES): Add chg-juke.sh.in, chg-rait.sh.in and
+         chg-null.sh.in
+
+2002-11-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c: Cleanup.
+
+2002-11-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amadmin.8.in: Document new --days option of balance subcommand.
+
+2002-11-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (days_diff): Make next_level0 more acurate.
+       * server-src/amadmin.c (balance): Improve output.
+
+2002-11-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c: Add Retry and Skip command to amrecover.
+
+2002-11-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * tape-src/output-tape.c (tape_tapefd_fsf): Must not be static.
+
+2002-11-19  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: Fix for LPRCMD not defined.
+
+2002-11-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Orion Poplawski <orion@colorado-research.com>
+
+       * server-src/planner.c (delay_dumps): Add the estimate size to all call
+         of delay_one_dump.
+
+2002-11-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: Increase width of some field.
+
+2002-11-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/scsi-solaris.c (SCSI_ExecuteCommand): Init ret to 0.
+
+2002-11-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (delete_file): j is int.
+       * changer-src/scsi-defs.h (B, B1): Check if already defined.
+       * server-src/taper.c: Some cast to int.
+       * tape-src/amdd.c (read_func, write_func): Complete prototype.
+       * tape-src/tapeio.h (tapefd_read, tapefd_write): return ssize_t, 
+         third argument is size_t.
+       * tape-src/tapeio.c: Ditto.
+       * tape-src/output-file.h (file_tapefd_read, file_tapefd_write): return 
+         ssize_t, third argument is size_t.
+       * tape-src/output-file.c: Ditto.
+       * tape-src/output-null.h (null_tapefd_read, null_tapefd_write): return 
+         ssize_t, third argument is size_t.
+       * tape-src/output-null.c: Ditto.
+       * tape-src/output-rait.h (rait_read, rait__write): return ssize_t,
+         third argument is size_t.
+       * tape-src/output-rait.c: Ditto.
+       * tape-src/output-tape.h (tape_tapefd_read, tape_tapefd_write): return 
+         ssize_t, third argument is size_t.
+       * tape-src/output-tape.c: Ditto.
+
+2002-11-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in: socklen_t default to int.
+       * common-src/dgram.c (dgram_recv): addrlen is socklen_t.
+       * common-src/stream.c (stream_server): len is socklen_t.
+       * recover-src/extract_list.c (add_file): j is int.
+
+2002-11-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (test_name_len) Remove variable.
+       * common-src/match.c (len_prefix): Change type to int.
+       * server-src/taper.c: Use %p to print pointer.
+       * tape-src/amdd.c (read_func, write_func):Change return type to ssize_t.
+       * tape-src/amdd.c (debug): Renamed to debug_amdd.
+       * tape-src/ammt.c (debug): Renamed to debug_ammt.
+
+2002-11-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * restore-src/amidxtaped.c: Fix restore from file.
+
+2002-11-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * restore-src/amidxtaped.c: Fix newline in string literal.
+
+2002-11-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.c (maxdumpsize): New option.
+       * server-src/conffile.h: Ditto.
+       * server-src/planner.c: Use maxdumpsize if set.
+       * example/amanda.conf.in: Document it.
+       * man/amanda.8.in: Document it.
+
+2002-11-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amfeatures.h (fe_amidxtaped_fsf, fe_amidxtaped_label,
+         fe_amidxtaped_device, fe_amidxtaped_host, fe_amidxtaped_disk,
+         fe_amidxtaped_datestamp, fe_amidxtaped_header, fe_amidxtaped_nargs,
+         fe_amidxtaped_config): New features.
+       * common-src/amfeatures.c (am_init_feature_set): Set new features.
+       * recover-src/extract_list.c: Send new protocol data to amidxtaped.
+       * restore-src/Makefile.am: amidxtaped.c need libamserver.
+       * restore-src/amidxtaped.c: Read new protocol data from amrecover.
+       * restore-src/amidxtaped.c: Use new configuration options.
+       * server-src/conffile.c (conf_amrecover_do_fsf,
+         conf_amrecover_check_label, conf_amrecover_changer): New config.
+       * server-src/conffile.h: New config options.
+       * example/amanda.conf.in: Document them.
+       * man/amanda.8.in: Document them.
+
+2002-11-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * autogen: touch config/config.h.in
+       * configure.in: Patch from autoupdate-2.53 and LIBOBJS.
+       * common-src/Makefile.am: Build versuff.o before version.o
+       * recover-src/Makefile.am: Remove work around for automake-1.2
+
+2002-11-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+        * configure.in: Remove --disable-libtool.
+        * */Makefile.am: Remove WANT_LIBTOOL.
+
+2002-11-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/chg-scsi.c (config_name, config_dir): Remove declaration.
+       * server-src/amadmin.c: Ditto.
+       * server-src/amcheck.c: Ditto.
+       * server-src/amcleanupdisk.c: Ditto.
+       * server-src/amflush.c: Ditto.
+       * server-src/amindexd.c: Ditto.
+       * server-src/amlabel.c: Ditto.
+       * server-src/amlogroll.c: Ditto.
+       * server-src/amtape.c: Ditto.
+       * server-src/amtrmidx.c: Ditto.
+       * server-src/amtrmlog.c: Ditto.
+       * server-src/diskfile.c: Ditto.
+       * server-src/driver.c: Ditto.
+       * server-src/dumper.c: Ditto.
+       * server-src/getconf.c: Ditto.
+       * server-src/planner.c: Ditto.
+       * server-src/reporter.c: Ditto.
+       * server-src/taper.c: Ditto.
+       * server-src/conffile.c: (config_name, config_dir): Add declaration.
+
+2002-11-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amrestore.8: Amrestore doesn't use a changer.
+
+2002-11-01  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in (SHELL): Don't set it, libtool do it.
+
+2002-10-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * config/ltmain.sh, config/libtool.m4i: Update from libtool 1.4.3.
+
+2002-10-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * restore-src/amrestore.c: New '-l <label>' flag, Do a rewind and
+         check the label before restoring.
+       * man/amrestore.8: Document -l flag.
+
+2002-10-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in (AM_HAVE_MT_FLAGS, AM_HAVE_MT_FILENO, AM_HAVE_MT_BLKNO,
+         AM_HAVE_MT_DSREG,AM_HAVE_MT_ERREG): Rename to HAVE_MT_FLAGS,
+         HAVE_MT_FILENO, HAVE_MT_BLKNO, HAVE_MT_DSREG and HAVE_MT_ERREG.
+       * tape-src/output-tape.c: Ditto.
+
+2002-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Undo patch of 2002-10-24. They are needed by amrecover.
+
+       * client-src/getfsent.h (open_fstab, close_fstab, get_fstab_nextentry,
+         is_local_fstype): Add Prototype.
+       * client-src/getfsent.c (open_fstab, close_fstab, get_fstab_nextentry,
+         is_local_fstype): remove Prototype.
+
+2002-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+        Patch by Paul Bijnens <paul.bijnens@xplanation.com>
+
+        * tape-src/tapetype.c: Detects and warns the user if the tape drive
+         has hardware compression enabled.
+
+2002-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * restore-src/amrestore.c: New '-f <fileno>' flag, Do a rewind and
+         'fsf <fileno>' if -f is set.
+       * man/amrestore.8: Document -f flag.
+
+2002-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amfeatures.h (fe_amindexd_fileno_in_OLSD,
+         fe_amindexd_fileno_in_ORLD): New amfeatures.
+       * common-src/amfeatures.c (am_init_feature_set): Set
+         fe_amindexd_fileno_in_OLSD and fe_amindexd_fileno_in_ORLD.
+       * recover-src/amrecover.h (struct DIR_ITEM): Add fileno.
+       * recover-src/display_commands.c (add_dir_list_item): Set fileno
+         in struct DIR_ITEM.
+       * recover-src/display_commands.c (suck_dir_list_from_server): Read
+         fileno if fe_amindexd_fileno_in_OLSD is set.
+       * recover-src/extract_list.c (struct EXTRACT_LIST): Add fileno.
+       * recover-src/extract_list.c (add_file): Read fileno if
+         fe_amindexd_fileno_in_ORLD is set.
+       * recover-src/extract_list.c (delete_file): Read fileno if
+         fe_amindexd_fileno_in_ORLD is set.
+       * server-src/amindexd.c (opaque_ls): Write fileno if
+         fe_amindexd_fileno_in_OLSD or fe_amindexd_fileno_in_ORLD are set.
+
+2002-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Doug Kingston <dpk@pobox.com>
+
+       * configure.in (NEED_PATH_ENV, IGNORE_UID_CHECK, IGNORE_FSTAB,
+         DONT_SUID_ROOT): Defined if on *-pc-cygwin.
+       * client-src/Makefile.am: Fix for cygwin.
+       * client-src/getfsent.c: Don't use fstab if IGNORE_FSTAB.
+       * client-src/killpgrp.c: Don't suid(0) if DONT_SUID_ROOT.
+       * client-src/rundump.c: Don't suid(0) if DONT_SUID_ROOT.
+       * client-src/runtar.c: Don't suid(0) if DONT_SUID_ROOT.
+       * client-src/selfcheck.c (check_suid): Don't check uid if
+         IGNORE_UID_CHECK.
+       * common-src/alloc.c (safe_env): Add PATH to ENV if NEED_PATH_ENV.
+       * recover-src/amrecover.c: Don't check uid if IGNORE_UID_CHECK.
+
+2002-10-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/getfsent.h (open_fstab, close_fstab, get_fstab_nextentry,
+         is_local_fstype): Remove Prototype.
+       * client-src/getfsent.c (open_fstab, close_fstab, get_fstab_nextentry,
+         is_local_fstype): Add Prototype.
+
+2002-10-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amindexd.c: New FEATURES command that read the features
+         set from the client and reply the features set of the server.
+       * recover-src/amrecover.h: include "amfeatures.h"
+       * recover-src/amrecover.c: Send the FEATURES command to the server
+         and read it's features set.
+
+2002-10-20  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/Makefile.am: Work around for CYGWIN.
+       * server-src/Makefile.am: Ditto.
+
+2002-10-20  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in: Remove empty command from $program_transform_name.
+
+2002-10-18  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (READ_TIMEOUT): Increased to 240*60.
+
+2002-10-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.3 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.3).
+
+2002-09-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/getfsent.c (open_fstab): Check if MNTTAB is defined.
+
+2002-09-19  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * NEWS: Changes in release 2.4.3.
+
+2002-09-19  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amverifyrun.sh.in: New program.
+       * man/amverifyrun.8.in: Man page for amverifyrun.
+       * configure.in (AC_OUTPUT): add man/amverifyrun.8 and
+         server-src/amverifyrun.sh.
+       * man/Makefile.am (SERVER_MAN_PAGES): Add amverifyrun.8.
+       * man/amanda.8.in: Add amdd, ammt and amverifyrun in SEE ALSO.
+       * man/amverify.8.in: Add amverifyrun(8) in SEE ALSO.
+       * server-src/Makefile.am (sbin_SCRIPTS): Add amverifyrun.
+
+2002-09-18  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amverify.sh.in: Accept runtapes as a third argument.
+       * man/amverify.8.in: Document it.
+
+2002-09-18  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * config/missing: Updated from automake-1.5.
+
+2002-09-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * config/config.guess: Updated from ftp://ftp.gnu.org/gnu/config/
+       * config/config.sub: Updated from ftp://ftp.gnu.org/gnu/config/
+
+2002-09-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendsize.c (getsize_dump): Print the fstype.
+       * client-src/sendbackup-dump.c (start_backup): Print the fstype.
+
+2002-09-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by  Florian Hars <hars@bik-gmbh.de>
+
+       * changer-src/chg-zd-mtx.sh.in: Fix default value for cleancycle.
+
+2002-09-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (extract_files): print tape drive
+         and host before asking to load tape.
+
+2002-09-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/taper.c (read_file): Initialize file,
+         stat(file.cont_filename) before opening it.
+         
+2002-09-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amverify.sh.in: Don't check that the device is
+         a character device, it could be a file: or rait:
+
+2002-09-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amfeatures.c (am_set_default_feature_set):
+         fe_rep_options_sendbackup_options is a default feature.
+
+2002-09-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Sort a disk in datestamp order.
+
+2002-09-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Text by Jean-Francois Malouin <Jean-Francois.Malouin@bic.mni.mcgill.ca>
+
+       * docs/EXCLUDE: Improve documentation.
+
+2002-09-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: Fix compilation error if LPRCMD is not defined.
+
+2002-08-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.3b4 released.
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.3b4).
+       * NEWS: Changes in release 2.4.3b4.
+
+2002-08-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Jason Brooks <jason0@mail.wrs.com>
+
+       * docs/chg-scsi.notes: New document.
+       * changer-src/chg-scsi.c: Adding printout of "emubarcode" values
+         in the debug file.
+       * changer-src/scsi-changer-driver.c: Added dlt8000 and L500 to
+         ChangerIO[].
+       * changer-src/sense.c: Added dlt8000 and L500 to SenseType[].
+
+2002-08-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * tape-src/output-null.c (null_tape_stat, null_tape_access): Use 
+         "/dev/null" instead of filename.
+
+2002-08-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/scsi-hpux.c: Add amanda copyright.
+
+2002-08-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/uparse.y: Fix compiler warning.
+
+2002-08-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amtrmidx.c: Continue if a directory doesn't exist.
+
+2002-08-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amanda.8.in (tapecycle): Improve documentation.
+
+2002-08-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Works with features.
+
+2002-08-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amfeatures.c (am_feature_to_string): Return the string
+         "UNKNOWNFEATURE" if no features.
+       * common-src/amfeatures.c (am_string_to_feature): Return NULL if the
+         string is "UNKNOWNFEATURE".
+
+2002-08-20  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/file.c (debug_agets): line_free was badly set when
+       the buffer size in increased.
+
+2002-07-19  John R. Jackson (jrj@purdue.edu)
+
+       * common-src/amanda.h: Fix bad #define.
+
+2002-07-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by David Munro <D.Munro@surrey.ac.uk>
+
+       * common-src/sl.c (new_sl): Alloc (sl_t) instead of (sl_t *).
+         
+2002-06-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Bug reported by
+         Jonathan R. Johnson <Jonathan.Johnson@MinnetonkaSoftware.com>
+
+       * server-src/reporter.c: Fix psfname filename.
+
+2002-05-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendbackup.c: Don't do compression if it is server side.
+       * client-src/sendbackup-dump.c: Ditto.
+       * client-src/sendbackup-gnutar.c: Ditto.
+
+2002-05-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Manuel Bouyer <bouyer@antioche.lip6.fr>
+
+       * server-src/taper.c (detach_buffers): Fix compilation with mmap.
+
+2002-04-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (extract_files): Set dump_device_name
+         after the call of okay_to_continue.
+
+2002-04-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       New features to describe the OPTIONS line of a REP packet.
+       * common-src/amfeatures.h: Add fetures fe_rep_options_maxdumps,
+         fe_rep_options_hostname, fe_rep_options_features and
+         fe_rep_options_sendbackup_options.
+       * common-src/amfeatures.c (am_init_feature_set): Add
+         fe_rep_options_features.
+       * client-src/selfcheck.c: Write REP packet according to server features.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+
+2002-04-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amfeatures.h: 
+            Rename fe_g_options_maxdump  to fe_req_options_maxdumps
+            Rename fe_g_options_hostname to fe_req_options_hostname
+            Rename fe_g_options_features to fe_req_options_features
+       * common-src/amfeatures.c: Ditto
+       * server-src/amcheck.c: Ditto
+       * server-src/dumper.c: Ditto
+       * server-src/planner.c: Ditto
+
+2002-04-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c: Check if it can send features, hostname or
+         maxdumps on the global options line. Don't send hostname and
+         maxdumps for a noop service.
+       * server-src/dumper.c: Ditto.
+       * server-src/planner.c: Ditto.
+
+2002-04-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendbackup.c: (optionstr): Add srvcomp-best and
+         srvcomp-fast options.
+
+2002-04-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c (start_host): Check the todo bit before
+         sending noop REQ.
+
+2002-04-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (parse_options, parse_g_options): Check
+         for duplication options.
+       * client-src/client_util.h (COMPR_SERVER_FAST, COMPR_SERVER_BEST):
+         Declare.
+       * client-src/selfcheck.c: Check for COMPR_FAST or COMPR_BEST.
+
+2002-04-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/selfcheck.c (host):Remove variable,use g_options->hostname.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+
+2002-04-20  Thomas Hepper <th@ant.han.de>
+       * changer-src/scsi-aix.c: Fixed bug with the setting of the GSC driver
+         Added detection and setting of device type tape/robot
+       * changer-src/scsi-bsd.c: Added detection and setting of device 
+         type tape/robot
+       * changer-src/scsi-cam.c: Added detection and setting of device 
+         type tape/robot
+       * changer-src/scsi-hpux_new.c: Added detection and setting of device 
+         type tape/robot
+       * changer-src/scsi-linux.c: Added detection and setting of device 
+         type tape/robot
+       * changer-src/scsi-solaris.c: Added detection and setting of device 
+         type tape/robot
+       * changer-src/scsi-irix.c: Added detection and setting of device 
+         type tape/robot
+       * changer-src/scsi-changer-driver.c: Now there is an device handler
+         for an generic tape and an generic robot.
+         The result length from the read element status is now checked
+         and only fields which are in this area are used.. (Some librarys
+         retrun only 4 byte, expected are 52)
+       * changer-src/scsi-defs.h: Fixed the some defines in 
+         ElementStatusPage_T, 
+
+2002-04-19  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (parse_g_options) New function to parse
+         the global options string.
+       * client-src/client_util.h (parse_g_options): Prototype.
+       * client-src/selfcheck.c: use parse_g_options.
+       * client-src/sendbackup.c: use parse_g_options.
+       * client-src/sendsize.c: use parse_g_options.
+
+2002-04-19  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/diskfile.c: Improve message for missing features.
+
+2002-04-19  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       Add many features.
+       * common-src/amfeatures.c (am_set_default_feature_set): New function
+         to set the default features set.
+       * common-src/amfeatures.h (am_set_default_feature_set): Prototype.
+       * common-src/amfeatures.h: Rename amanda_feature_auth_keyword to
+         fe_options_auth.
+       * client-src/client_util.c: Check features.
+       * server-src/amcheck.c: Ditto.
+       * server-src/diskfile.c: Ditto.
+       * server-src/driverio.c: Ditto.
+       * server-src/planner.c: Ditto.
+       * server-src/diskfile.h (optionstr): Change prototype.
+       * client-src/sendsize.c: Fix compiler warning.
+
+2002-04-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amfeatures.c: Renamed from features.c
+       * common-src/amfeatures.h: Renamed from features.h
+       * common-src/Makefile.am: Rename features to amfeatures.
+       * client-src/amandad.c: Ditto.
+       * client-src/client_util.h: Ditto.
+       * client-src/selfcheck.c: Ditto.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * server-src/amcheck.c: Ditto.
+       * server-src/diskfile.h: Ditto.
+       * server-src/dumper.c: Ditto.
+       * server-src/planner.c: Ditto.
+       * server-src/taper.c: Ditto.
+
+2002-04-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.c: Default dumporder set to "ttt".
+       * server-src/driver.c: If dumporder is too short, use t and T.
+       * man/amanda.8.in: Default dumporder set to "ttt".
+
+2002-04-13  John R. Jackson (jrj@purdue.edu)
+
+       * common-src/features.c: Add amanda_feature_auth_keyword feature so
+         authorization in the OPTIONS string is backward compatible.
+       * common-src/features.h: Ditto.
+       * client-src/client_util.c: Ditto.
+       * client-src/client_util.h: Ditto.
+       * client-src/selfcheck.c: Ditto.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * server-src/diskfile.c: Ditto.
+
+2002-04-13  John R. Jackson (jrj@purdue.edu)
+
+       * server-src/diskfile.c: Fix memory leak.
+
+2002-04-13  John R. Jackson (jrj@purdue.edu)
+
+       * common-src/features.c: New file.  Add support for feature sets so
+         different Amanda versions can work together.
+       * common-src/features.h: Ditto.
+       * common-src/Makefile.am: Ditto.  Add "features" test program.
+       * client-src/amandad.c: Add "noop" service to return the feature set.
+       * client-src/selfcheck.c: Accept and return a feature set in OPTIONS.
+         Improve parsing.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * common-src/error.c: Use strcasecmp.
+       * common-src/protocol.c: Use dbprintf for PROTO_DEBUG and improve
+         messages.  Improve parsing.
+       * common-src/security.c: Improve parsing.
+       * server-src/amcheck.c: Ask for client features via "noop" before
+         doing the real "selfcheck" service requests.  Improve parsing.
+       * server-src/amflush.c: Minor coding format cleanup.
+       * server-src/diskfile.c: Initialize the features hosttype field.
+       * server-src/diskfile.h: Add the features hosttype field.
+       * server-src/driver.c: Save the features from the schedule.  Clean
+         up some error messages.
+       * server-src/driverio.c: Add features string to several commands.
+       * server-src/dumper.c: Deal with features string in commands.  Improve
+         parsing.
+       * server-src/planner.c: Ask for client features via "noop" before
+         doing the real "sendsize" service requests.  Improve parsing.
+       * server-src/server_util.c: Minor coding cleanup.
+       * server-src/server_util.h: Increase the number of args allowed on
+         commands.
+       * server-src/taper.c: Deal with features string in commands.  Improve
+         parsing.
+
+2002-04-11  John R. Jackson (jrj@purdue.edu)
+
+       * common-src/stream.c: Clean up an error message.
+
+2002-04-09  John R. Jackson (jrj@purdue.edu)
+
+       * server-src/driver.c: Fix send of QUIT to taper when it is down.
+
+2002-04-07  John R. Jackson (jrj@purdue.edu)
+
+       * server-src/reporter.c: Move column routines to conffile.c so amcheck
+         can use them in its tests.  Do not abort on several failures, but
+         generate messages in the FAILURE AND STRANGE DUMP SUMMARY section.
+       * server-src/conffile.c: Move column routines to here.
+       * server-src/conffile.h: Ditto.
+       * server-src/amcheck.c: Add several config file tests.
+       * server-src/logfile.c: Change "reporter" to "amreport".
+
+2002-04-07  John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Add /usr/local/sbin to LOCPATH.
+
+2002-03-31  John R. Jackson (jrj@purdue.edu)
+
+       * server-src/amcheck.c: Send maxdumps and hostname in packet OPTIONS.
+
+2002-03-31  John R. Jackson (jrj@purdue.edu)
+
+       * changer-src/scsi-defs.h: Fix compiler warning and bug it was hiding.
+       * changer-src/scsi-solaris.c: Ditto.
+
+2002-03-31  John R. Jackson (jrj@purdue.edu)
+
+       * client-src/amandad.c: Add relative timestamps to a lot of debug
+         file messages, and add more messages, to better track what is
+         going on.  Various general cleanup.
+       * client-src/calcsize.c: Ditto.
+       * client-src/client_util.c: Ditto.
+       * client-src/selfcheck.c: Ditto.
+       * client-src/sendbackup-dump.c: Ditto.
+       * client-src/sendbackup-gnutar.c: Ditto.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendbackup.h: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * common-src/Makefile.am: Ditto.
+       * common-src/amanda.h: Ditto.
+       * common-src/clock.c: Ditto.
+       * common-src/clock.h: Ditto.
+       * common-src/debug.c: Ditto.
+       * common-src/dgram.c: Ditto.
+       * common-src/error.c: Ditto.
+       * common-src/pipespawn.c: Ditto.
+       * common-src/security.c: Ditto.
+       * common-src/stream.c: Ditto.
+       * common-src/util.c: Ditto.
+       * man/amanda.8.in: Ditto.
+       * restore-src/amidxtaped.c: Ditto.
+       * restore-src/amrestore.c: Ditto.
+       * server-src/amindexd.c: Ditto.
+       * server-src/getconf.c: Ditto.
+       * server-src/planner.c: Ditto.
+
+2002-03-31  John R. Jackson (jrj@purdue.edu)
+
+       * client-src/sendsize.c: Pay attention to the spindle number.
+
+2002-03-30  John R. Jackson (jrj@purdue.edu)
+
+       * server-src/planner.c: General delay_dumps code cleanup.
+
+2002-03-30  John R. Jackson (jrj@purdue.edu)
+
+       * server-src/planner.c: Make sure individual dumps larger than a tape
+         are not added back into the schedule.  Found by Uncle George
+         <gatgul@voicenet.com>.
+
+2002-03-29  John R. Jackson (jrj@purdue.edu)
+
+       * man/amanda.8.in: Move "comment" in tapetype after inclusion of
+         previous definition.  Found by Uncle George <gatgul@voicenet.com>.
+
+2002-03-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (fixup_relative): New function to prepend 
+         the dirname if relative.
+       * client-src/client_util.c (build_exclude, build_include): Use 
+         fixup_relative.
+       * client-src/client_util.c (parse_options): Do not prepend the dirname.
+       * client-src/selfcheck.c (check_options): Don't generate ERROR for samba
+         if optional is set.
+
+2002-03-24  John R. Jackson (jrj@purdue.edu)
+
+       * common-src/debug.c: Change dbopen() message slightly to match what
+         amdump generates, making it easier to parse.
+
+2002-03-24  John R. Jackson (jrj@purdue.edu)
+
+       * common-src/Makefile.am: Move clock routines to common-src so
+         everyone may use them.
+       * server-src/Makefile.am: Ditto.
+
+2002-03-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendbackup-gnutar.c: Fix use of no_record.
+
+2002-03-24  Thomas Hepper ( th@ant.han.de)
+       * changer-src/chg-scsi-chio.c: Fixed problems introduced by the agets change
+       * client-src/sendbackup-dump.c: Fixed compile problem on AIX, no_record
+         is no longeer defined, ist is now options->no_record.
+
+2002-03-24  John R. Jackson (jrj@purdue.edu)
+
+       * client-src/amandad.c: Make sure argv[0] is valid before using it.
+       * restore-src/amidxtaped.c: Ditto.
+       * server-src/amindexd.c: Ditto.
+
+2002-03-24  John R. Jackson (jrj@purdue.edu)
+
+       * client-src/client_util.c: Use the Amanda memory allocation code.
+       * client-src/sendbackup-gnutar.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * common-src/match.c: Ditto.
+       * recover-src/amrecover.c: Ditto.
+       * recover-src/display_commands.c: Ditto.
+       * recover-src/extract_list.c: Ditto.
+       * restore-src/amidxtaped.c: Ditto.
+       * server-src/amflush.c: Ditto.
+       * server-src/disk_history.c: Ditto.
+       * server-src/driver.c: Ditto.
+       * server-src/dumper.c: Ditto.
+       * server-src/list_dir.c: Ditto.
+       * common-src/amanda.h: Always pass the source file and line number
+         to the memory routines to make it easier to debug.
+       * common-src/alloc.c: Ditto.
+       * common-src/file.c: Ditto.
+       * common-src/dgram.c: Ditto.
+       * common-src/dgram.h: Ditto.
+
+2002-03-24  Thomas Hepper ( th@ant.han.de)
+       * changer-src/chg-scsi.c: Fixed problems introduced by the agets change
+       * changer-src/chg-scsi.c (MapBarCode): Fixed error in eof handling
+         eof was not correctly detected, now use the feof function.
+       * changer-src/scsi-aix.c (SCSI_OS_Version()): New function to print
+         the rcsid 
+       * changer-src/scsi-aix.c: same as above
+       * changer-src/scsi-cam.c: same as above
+       * changer-src/scsi-hpux_new.c: same as above
+       * changer-src/scsi-irix.c: same as above
+       * changer-src/scsi-linux.c: same as above
+       * changer-src/scsi-solaris.c: same as above
+       * changer-src/scsi-changer-driver.c (DLT448ElementStatus()): Fixed 
+         error messages. Fixed some errors with the barcode handling.
+
+2002-03-23  John R. Jackson (jrj@purdue.edu)
+
+       * changer-src/chg-scsi-chio.c: Use agets instead of fgets.
+       * changer-src/chg-scsi.c: Use agets instead of fgets.
+       * client-src/client_util.c: Use agets instead of fgets.
+       * recover-src/amrecover.c: Clean up output on EOF.
+       * recover-src/extract_list.c: Use agets instead of direct stdio.
+         Clean up output on EOF.  Add '?' help.
+       * recover-src/set_commands.c: Quote the new device in the verify
+         output to make it stand out.
+       * server-src/amflush.c: Clean up output on EOF.  Clean up output
+         when multiple holding disk areas selected.  Clean up parsing.
+         Loop until valid user response.
+       * server-src/find.c: Do not complain if log file is missing for
+         a new (datestamp == 0) tape.
+       * server-src/holding.c: Use agets instead of fgets. Clean up
+         interactive input and output.
+
+2002-03-23  John R. Jackson (jrj@purdue.edu)
+
+       * client-src/selfcheck.c: Fix a compiler warning.
+       * client-src/sendbackup.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+
+2002-03-23  John R. Jackson (jrj@purdue.edu)
+
+       * client-src/getfsent.c (close_fstab()): Call endfsent() instead
+         of fclose(), if available.
+
+2002-03-23  John R. Jackson (jrj@purdue.edu)
+
+       * common-src/dbprintf (debug_printf): Make sure errno is preserved
+         across dbprint() calls.
+
+2002-03-23  John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Add -R$dir as well as -L$dir on Solaris when processing
+         --with-libraries to support shared libraries of support products.
+
+2002-03-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/tapefile.c (write_tapelist): Write to a temp file and
+         rename it.
+       * server-src/amlabel.c: Do not rename the tapelist file.
+       * server-src/taper.c (label_tape): Do not rename the tapelist file.
+
+2002-03-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (parse_options): Do not check if the
+         exclude file exist, it's done later.
+
+2002-03-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (parse_options): Parse exclude-optional and
+         include-optional.
+       * client-src/client_util.h (option_t): New exclude_optional and
+         include_optional field.
+       * man/amanda.8.in: Document optional.
+       * server-src/amadmin.c (disklist_one): Display optional.
+       * server-src/conffile.c: Parse optional keyword.
+       * server-src/conffile.h (dumptype_t): New exclude_optional and
+         include_optional field.
+       * server-src/diskfile.c (read_diskline): Copy optional bits.
+       * server-src/diskfile.c (optionstr): Print optional bits.
+       * server-src/diskfile.h (disk_t): New exclude_optional and
+         include_optional field.
+       * server-src/planner.c (getsize): Use new sendsize format if optional
+         bits are used.
+
+2002-03-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (dump_to_tape): Call start_degraded_mode() if
+         taper failed.
+
+2002-03-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (extract_files_setup): Add ^$ to host.
+
+2002-03-20  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch from Michael Frankowski <mfrankow@winternet.com>
+
+       * client-src/sendbackup-gnutar.c: Test for subdir before dbprintf.
+
+2002-03-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (init_options): New function.
+       * client-src/client_util.h (init_options): Prototype.
+       * client-src/sendsize.c (main): Use init_options.
+
+2002-03-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client-util.c: Check for include and exclude files.
+
+2002-03-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Fix.
+       * server-src/conffile.c(get-compress): Change message for bad
+         compress argument.
+
+2002-03-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Fix.
+
+2002-03-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendbackup-dump.c: use amdevice as argument to
+         amname_to_fstype.
+
+2002-03-08  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.3b3 released
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.3b3)
+
+2002-03-08  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * ReleaseNotes: New file.
+       * NEWS: New item for 2.4.3b3.
+
+2002-03-07 John R. Jackson (jrj@purdue.edu)
+
+       * changer-src/chg-zd-mtx.sh.in: Allow whitespace on a VolumeTag line.
+         Compliments of Christopher McCrory <chrismcc@pricegrabber.com>.
+
+2002-03-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/amrecover.h (list_disk): Prototype.
+       * recover-src/set_commands.c (list_disk): New function.
+       * recover-src/uparse.y: parse LISTDISK.
+       * recover-src/uscan.l: listdisk keyword.
+       * recover-src/help.c: help for listdisk.
+       * man/amrecover.8.in: Doc for listdisk.
+       * server-src/amindexd.c: New LISTDISK command.
+       * docs/INDEXING: Document LISTDISK command.
+
+2002-03-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Better output for autoflush.
+
+2002-03-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Fix.
+
+2002-03-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (disklist_one): Print dp->device.
+       * server-src/amcheck.c (start_host): Send device if specified.
+       * server-src/amstatus.pl.in: Parse line with device.
+       * server-src/diskfile.c (parse_diskline): Parse device.
+       * server-src/diskfile.c (match_disklist): Match on device.
+       * server-src/diskfile.h (disk_t): New field device.
+       * server-src/driverio.c: (dumper_cmd): Send device.
+       * server-src/dumper.c (main): Parse device in request.
+       * server-src/dumper.c (start_dump): New device argument, send
+         device to client.
+       * server-src/planner.c (getsize): Send device to client.
+       * server-src/server_util.h (MAX_ARGS): Set it to 12.
+       * client-src/client_util.c (add_include, build_exclude, build_include,
+         parse_options): New device argument.
+       * client-src/client_util.h (build_exclude,build_include,parse_options):
+         New prototype.
+       * client-src/selfcheck.c: Use device.
+       * client-src/sendbackup-dump.c: Use device.
+       * client-src/sendbackup-gnutar.c: Use device.
+       * client-src/sendbackup.c: Use device.
+       * client-src/sendbackup.h (start_backup): New device argument.
+       * client-src/sendsize.c: Use device.
+       * man/amanda.8.in: Document new disklist syntax.
+       * example/disklist: Give example.
+
+2002-03-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Write "wait to flush" only if waittaper
+         is requested.
+
+2002-03-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Fix for failed tape.
+
+2002-02-18  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amanda.8.in: Document multiple exclude.
+       * man/amanda.8.in: Document include.
+
+2002-02-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client-util.c (add_include): Include are glob expression.
+
+2002-02-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/debug.c (debug_open); Don't try to renmae an already
+         renamed file.
+
+2002-02-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.c (dump_configuration): Print multiple
+         exclude and include.
+
+2002-02-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (add_exclude, add_include): Typo.
+
+2002-02-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (build_include, build_exclude): Fix for
+         bad eof detection.
+
+2002-02-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (get_name): Create a file name.
+       * client-src/client_util.c (build_name): Remove old files,
+         build an unused file name.
+       * client-src/client_util.c (add_exclude): Add an exclude pattern to
+         the exclude file.
+       * client-src/client_util.c (add_include): Add an include to the
+         include file.
+       * client-src/client_util.c (build_exclude): Concat all excludes in
+         one file.
+       * client-src/client_util.c (build_include): Concat all includes in
+         one file.
+       * client-src/client_util.h (build_exclude, build_include): Prototype.
+       * client-src/selfcheck.c.diff (check_options): Call build_exclude
+         and build_include.
+       * client-src/sendsize.c.diff: Call gtar with one
+         exclude file/include file.
+       * client-src/sendbackup-gnutar.c.diff: Call gtar with one
+         exclude file/include file.
+
+2002-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amanda.h (amfree): Change e local variable to e__errno.
+       * common-src/amanda.h (strappend): Change t local variable to t_t_t.
+
+2002-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendsize.c: Set include_file and include_list to NULL
+         when using old protocol.
+       * client-src/sendbackup-gnutar.c: Include "." when using old protocol.
+
+2002-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.h (dumptype_t): Add include_file and include_list.
+       * server-src/conffile.c: Read include.
+       * server-src/diskfile.h (disk_t): Add include_file and include_list.
+       * server-src/diskfile.c (optionstr): Add include to the optionstr.
+       * server-src/amadmin.c (disklist_one): Print include.
+       * server-src/planner.c: Use new protocol if include is used.
+       * client-src/client_util.h (option_t): Add include_file and include_list
+       * client-src/client_util.c (parse_options): Parse include.
+       * client-src/selfcheck.c (check_options): Print ERROR if include are
+         used for SAMBA or DUMP.
+       * client-src/sendsize.c: Send include to gnutar.
+       * client-src/sendbackup-gnutar.c: Send include to gnutar.
+
+2002-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/client_util.c (parse_options): Check that files from 
+         'exclude list' exist'.
+       * client-src/selfcheck.c (check_options): Give ERROR if multiple 
+         exclude are used with samba or if exclude are used with DUMP.
+
+2002-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client_src/client_util.c (parse_options): Function to parse
+         the option string.
+       * client_src/client_util.h (parse_options): Prototype.
+       * client_src/client_util.h (option_t): Struct for options.
+       * client_src/Makefile.am: Compile client_util.
+       * client_src/selfcheck.c: Use new option_t and multiple exclude.
+       * client_src/sendbackup.h: Use new option_t and multiple exclude.
+       * client_src/sendbackup.c: Use new option_t and multiple exclude.
+       * client_src/sendbackup-dump.c: Use new option_t and multiple exclude.
+       * client_src/sendbackup-gnutar.c: Use new option_t and multiple exclude.
+       * client_src/sendsize.c: Use new option_t and multiple exclude.
+       * server-src/conffile.h: Use sl_t for exclude_file and exclude_list.
+       * server-src/conffile.c: Multiple exclude.
+       * server-src/diskfile.h: Use sl_t for exclude_file and exclude_list.
+       * server-src/diskfile.c: Multiple exclude.
+       * server-src/planner.c: Multiple exclude.
+
+2002-02-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/pipespawn.c (pipespawnv): New funtion taking an
+         argv argument.
+       * common-src/pipespawn.h (pipespawnv): Prototype.
+
+2002-02-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.h: Use sl_t instead of holding_t
+       * server-src/holding.c: Ditto.
+       * server-src/amcleanupdisk.c: Ditto.
+       * server-src/amflush.c: Ditto.
+       * server-src/find.c: Ditto.
+       * server-src/planner.c: Ditto.
+
+2002-02-11 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: AIX needs the "other" getconf argument to find out
+         about large file support (XBS5_ILP32_OFFBIG instead of LFS).
+
+2002-02-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/sl.h: New header file
+       * common-src/sl.c: New file for list of string struct.
+       * common-src/Makefile.am: Compile sl.c
+
+2002-02-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/chg-zd-mtx.sh.in: Don't use '^' in expr match argument.
+
+2002-02-10 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Add new file-pad tapetype option to take the place
+         of a positive/negative blocksize.  Blocksize may now only be
+         positive.  File-pad defaults to "true" which pads the last tape
+         record like it always has.
+       * man/amanda.8.in: Ditto.
+       * server-src/amlabel.c: Ditto.
+       * server-src/conffile.c: Ditto.  Fix typo in conffile test program.
+       * server-src/conffile.h: Ditto.
+       * server-src/planner.c: Ditto.
+       * server-src/taper.c: Ditto.
+
+2002-02-10 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Save the ./configure args and display them in the
+         version string (e.g. amandad*debug and "amadmin xx version").
+       * common-src/genversion.c: Ditto.
+
+2002-02-10 John R. Jackson (jrj@purdue.edu)
+
+       * common-src/alloc.c: Fix type mismatch issues discovered by splint
+         (www.splint.org).  Compliments of jens persson <jens@persson.cx>.
+       * common-src/debug.c: Ditto.
+       * common-src/dgram.c: Ditto.
+       * common-src/file.c: Ditto.
+       * common-src/fileheader.c: Ditto.
+       * common-src/fileheader.h: Ditto.
+       * common-src/getcwd.c: Ditto.
+       * common-src/match.c: Ditto.
+       * common-src/security.c: Ditto.
+       * common-src/stream.c: Ditto.
+       * common-src/strstr.c: Ditto.
+       * common-src/token.c: Ditto.
+       * recover-src/amrecover.c: Ditto.
+       * recover-src/display_commands.c: Ditto.
+       * recover-src/extract_list.c: Ditto.
+       * recover-src/set_commands.c: Ditto.
+       * server-src/reporter.c: Ditto.
+
+2002-02-10 John R. Jackson (jrj@purdue.edu)
+
+       * changer-src/chg-zd-mtx.sh.in: Major cleanup and general overhaul.
+       * docs/TAPE.CHANGERS: Cleanup.
+
+2002-02-09 John R. Jackson (jrj@purdue.edu)
+
+       * common-src/arglist.h: Clean up gcc detection of printf style variable
+         argument list functions.
+       * changer-src/scsi-changer-driver.c: Ditto.
+       * common-src/debug.c: Ditto.
+       * common-src/error.c: Ditto.
+       * common-src/snprintf.c: Ditto.
+       * common-src/token.c: Ditto.
+       * common-src/token.h: Ditto.
+       * server-src/amindexd.c: Ditto.
+       * server-src/conffile.c: Ditto.
+       * server-src/diskfile.c: Ditto.
+       * server-src/logfile.c: Ditto.
+       * server-src/logfile.h: Ditto.
+       * server-src/server_util.c: Ditto.
+
+2002-02-09 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Must look in both strings.h and string.h when trying
+         to find function declarations (strncasecmp was not found on AIX
+         but is really there and our override caused a mismatch error).
+
+2002-02-09 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Add code to test for a type defined in other than the
+         autoconf expected locations.  Use it to look for socklen_t.
+
+2002-02-08 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/amadmin.c (check_dumpuser): Make it fatal to attempt to
+         do an operation that would alter any files when run as someone other
+         than the dump user from amanda.conf.  This should prevent files from
+         ending up with incorrect ownership.
+
+2002-02-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amrecover.8.in (settape): Document that the hostname is required
+         if the protocol (tape:, file:, rait:, null:) is specified.
+       * man/amrecover.8.in (settape): Document that it is posible to
+         change the tape device when asked to load tape.
+
+2002-02-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.c (scan_holdingdir): Create the list in
+         datestamp order.
+
+2002-02-02 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Add unistd.h to list of places to look for ruserok()
+         declaration.  Reported by John Koenig <jfkoenig@vipb.com> on ALPHA
+         running OSF1 v5.1
+
+2002-02-01  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Reported by Roland E. Lipovits <rel@lipo.at0.net>
+
+       * server-src/amstatus.pl.in: Don't double-counts the failed
+         estimate partitions.
+
+2002-01-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in: New --with-maxtapeblocksize with a default of 32.
+       * common-src/amanda.h: MAX_TAPE_BLOCK_KB is defined in amanda.h
+
+2002-01-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/fileheader.c (build_header): Never write the
+         BLOCKSIZE= line.
+       * common-src/fileheader.c (parse_file_header): Do not parse the
+         BLOCKSIZE= line.
+
+2002-01-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/fileheader.c (build_header): Write the BLOCKSIZE= line
+         after the dd if=... line.
+       * common-src/fileheader.c (parse_file_header): Ignore unknown line.
+
+2002-01-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c: Init code to 0.
+
+2002-01-29 John R. Jackson (jrj@purdue.edu)
+
+       * tape-src/output-tape.c (tape_tapefd_fsf): Some systems cannot deal
+         with large stack variables, so allocate tape I/O buffers dynamically.
+       * tape-src/tapeio.c (tapefd_rdlabel): Ditto.
+
+2002-01-25 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/driver.c: Log non-zero exit codes and signals from all
+         the dumpers and taper.
+
+2002-01-25 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/amindexd.c: Clean up reporting of errors by gethostby*()
+         functions.  Make sure they always report what they were trying to
+         look up, and don't bother reporting errno (it would be h_errno).
+       * server-src/dumper.c: Ditto.
+       * server-src/planner.c: Ditto.
+
+2002-01-17  Thomas Hepper <th@ant.han.de>
+
+       * changer-src/scsi-changer-driver.c (DecodeSense): Check if it is
+         an normal or an extended result from request sense, and only
+         print the correct infos for the detected type.
+       * changer-src/scsi-changer-driver.c (RequestSense): Use the passed
+         pointer to store the result from request sense. Do not allocate
+         an own buffer. Fixed the bufer size which is passed to teh SCSI
+         function.
+       * changer-src/scsi-changer-driver.c (ChangerStatus): Use the macros
+         for setting the device to use for query, don't use fix values.
+       * changer-src/scsi-changer-driver.c (SCSI_Run): skip the sleep
+         if the status is ok, only sleep if we will loop.
+       * changer-src/scsi-changer-driver.c (DebugPrint): Print an timestamp
+         to see how many time is used between the prints and so see where
+         the time is gone.
+
+2002-01-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/fileheader.h (dumpfile_t): Add blocksize field.
+       * common-src/fileheader.h (build_header): Change prototype.
+       * common-src/fileheader.c (fh_init): blocksize default to
+         DISK_BLOCK_BYTES.
+       * common-src/fileheader.c (parse_file_header): Parse BLOCKSIZE= line.
+       * common-src/fileheader.c (build_header): Remove blocksize parameter,
+         write the BLOCKSIZE= line.
+       * tape-src/tapeio.c: set file.blocksize, Change call to build_header.
+       * restore-src/amrestore.c: Ditto.
+       * server-src/dumper.c: Ditto.
+       * server-src/taper.c: Ditto.
+       * server-src/holding.c: Ditto.
+
+2002-01-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/scsi-changer-driver.c (SCSI_ReadElementStatus):
+         set ret to -1.
+
+2002-01-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c: Check for dp->todo.
+
+2002-01-10   Thomas Hepper <th@ant.han.de>
+
+        * changer-src/scsi-changer-driver.c: Fixed prototype for SCSI_ReadElementStatus
+        * changer-src/scsi-changer-driver.c (eject_tape): Fixed error in the rewind 
+        * changer-src/scsi-changer-driver.c (unload): Fixed error in the rewind logic
+        * changer-src/scsi-changer-driver.c (load): Fixed error in the rewind logic
+        * changer-src/scsi-changer-driver.c (GetElementStatus): Fixed error in the parameter list to SCSI_ReadElementStatus
+        * changer-src/scsi-changer-driver.c (SCSI_ReadElementStatus): Changed the logic, if the size for DescriptorSize
+         is 0 try to get the size the old way, if this parameter greate 0 take this value as the size for the data
+         buffer which is used to hold the result. May fix a problem with an HP changer
+       * changer-src/scsi-defs.h: Updated the structs for the different element types (Media Changer, Storage, Tape, Import)
+
+
+2002-01-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Harlan Stenn <Harlan.Stenn@pfcs.com>
+
+       * changer-src/chg-scsi.c: Typo.
+
+2002-01-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/Makefile.am: Run `perl -c' on perl script.
+       * client-src/Makefile.am: Ditto.
+       * server-src/Makefile.am: Ditto.
+
+2002-01-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Reported by Geert Uytterhoeven <geert@linux-m68k.org>
+
+       * README: Amanda compile on Linux/m68k.
+
+2002-01-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/chg-rth.pl.in: Typo. fi -> }.
+
+2002-01-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Harlan Stenn <Harlan.Stenn@pfcs.com>
+
+       * changer-src/chg-chio.pl.in: Typo. fi -> }.
+       * changer-src/chg-chio.pl.in (prefix, exec_prefix): Set correctly.
+       * changer-src/chg-chio.pl.in (max_picker): Init to -1.
+
+2002-01-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (okay_to_continue_tape): Ignore \n
+         at end of string.
+
+2002-01-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amoverview.pl.in: Ignore some line from amadmin.
+
+2002-01-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.3b2 released
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.3b2)
+       * NEWS: New feature of amanda-2.4.3b2
+
+2002-01-01  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * tape-src/output-tape.c (tape_tapefd_rewind, tape_tapefd_unload):
+         Init rc to -1.
+       * changer-src/scsi-irix.c (SCSI_OpenDevice): Cast to int.
+       * common-src/match.c (clean_regex): Cast to int.
+
+2001-12-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * config/ltconfig: Remove.
+       * config/ltmain.sh, config/libtool.m4i: Update from libtool 1.4.2.
+       * config/config.guess: Update from
+         ftp://ftp.gnu.org/gnu/config/config.guess.
+       * config/config.sub: Update from
+         ftp://ftp.gnu.org/gnu/config/config.sub.
+       * config/depcomp, config/install-sh, config/missing,
+         config/mkinstalldirs: Update from automake 1.5.
+       * config/Makefile.am (EXTRA_DIST): Remove ltconfig.
+
+2001-12-31  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Harlan Stenn <Harlan.Stenn@pfcs.com>
+
+       * configure.in: Add missing [.
+
+2001-12-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c: Do not go in degraded mode in nodump mode.
+       * server-src/conffile.c:Check many options to be sure they are positive.
+
+2001-12-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/chg-scsi.c (get_relative_target): return -1;
+       * changer-src/scsi-irix.c (SCSI_ExecuteCommand): Remove Zero variable.
+       * common-src/amanda.h: include strings.h if HAVE_STRINGS_H is defined.
+       * server-src/amadmin.c (info_one): Remove lev0date variable.
+       * server-src/amadmin.c (import_db): Remove vers_comment variable.
+       * server-src/amindexd.c (main): Remove arg_len variable.
+       * server-src/amtrmidx.c (main): Remove level_position and
+         datestamp_position variables.
+       * server-src/changer.c (changer_current): Remove checked variable.
+       * server-src/conffile.c (read_confline): Check value of RESERVE.
+       * server-src/conffile.c (get_tapetype): Check value of LENGTH and
+         FILEMARK.
+       * server-src/diskfile.h: bit field of 1 bit must be unsigned.
+       * server-src/driver.c (main): Don't check the value of RESERVE.
+       * server-src/driver.c (find_diskspace): Remove as_pref variable.
+       * server-src/driverio.c (getresult): cast cmd_t.
+       * server-src/dumper.c (update_dataptr): save_type is a filetype_t.
+       * server-src/find.c (search_logfile): Remove host_undo_ch and
+         disk_undo_ch variables.
+       * server-src/holding.c (pick_datestamp): Remove result variable.
+       * server-src/server_util.c (getcmd): Loop on a cmd_t variable.
+       * server-src/taper.c (tape_writer_side): Remove out_open variable.
+       * tape-src/tapeio.c (tapefd_close): Cast to (void *).
+
+2001-12-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * restore-src/amrestore.c: Fix compiler warning.
+       * changer-src/chg-scsi.c: Ditto.
+       * common-src/fileheader.c: Ditto.
+       * changer-src/scsi-changer-driver.c: Ditto.
+       * changer-src/scsi-defs.h: Ditto.
+       * client-src/selfcheck.c: Ditto.
+
+2001-12-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in: Set MAX_TAPE_BLOCK_KB on linux.
+
+2001-12-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Blaz Zupan <blaz@amis.net>
+
+       * changer-src/chg-zd-mtx.sh.in: typo.
+
+2001-12-20 Thomas Hepper <th@ant.han.de>
+       * changer-src/scsi-changer-driver.c: Return error if the find_empty returns an error
+         In function LogSense try to reset the error counter. Fixed wrong pDev struct pointer in
+         TapeStatus. Must be INDEX_TAPECTL and not INDEX_TAPE at the start of the function
+
+2001-12-18  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/selfcheck.c (check_access): New function (old check_file 
+         function).
+       * client-src/selfcheck.c (check_file): Check that the filename is a 
+         file.
+       * client-src/selfcheck.c (check_dir): Check that dirname is a directory.
+
+2001-12-18  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Henning Schmiedehausen <henning@forge.intermeta.de>
+
+       * common-src/file.c (safe_cd): Create the AMANDA_DBGDIR and 
+         AMANDA_TMPDIR directory.
+
+2001-12-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/Makefile.am (pkgdata_DATA): Include RAIT and VTAPE-API.
+
+2001-12-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amverify.sh.in: Check that @AMANDA_TMPDIR@ exist.
+       * server-src/amrmtape.sh.in: Ditto.
+
+2001-12-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/Makefile.am: fix setting of libexec_PROGRAMS.
+
+2001-12-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Work with amflush log.
+
+2001-12-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (nodump): new argument, Don't start the dumpers
+         if set.
+       * server-src/holding.c (get_flush): chdir to original cwd.
+       * server-src/reporter.c: accept driver and amflush line in log.
+       * server-src/amflush.c: exec driver to do the flushing.
+
+2001-12-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Fixup for estimate, write flush line.
+
+2001-12-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c (output_summary): Set origsize and 
+         outsize correctly.
+
+2001-12-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (start_some_dumps): Fixup length of dumporder.
+
+2001-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c: You can change the tape device
+         between each tape.
+
+2001-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * restore-src/amrestore.c (restore): try to find the next chunk
+         in the current directory.
+
+2001-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * example/amanda.conf.in: typo.
+
+2001-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       
+       Patch by Roland E. Lipovits <rel@lipo.at0.net>
+       * example/amanda.conf.in: typo.
+
+2001-12-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c, server-src/taper.c: Replace TRY_AGAIN
+       by TRYAGAIN.
+
+2001-11-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.3b1 released
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.3b1)
+       * NEWS: New feature of amanda-2.4.3
+
+2001-11-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/diskfile.c (lookup_host): Match must be exact.
+
+2001-11-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c: Add host, disk, datestamp and level on
+       FLUSH line. Add datestamp on DUMP line.
+       * server-src/driver.c (read_flush): Read new format of FLUSH line.
+       * server-src/driver.c (read_schedule): Read new format of DUMP line.
+       * server-src/amflush.c: Write a datestamp on stderr.
+       * server-src/amdump.sh.in: Write a datestamp on stderr.
+       * server-src/amstatus.pl.in: Works with autoflush.
+
+2001-11-08  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.c (autoflush): New configuration options.
+       * server-src/conffile.h (autoflush): New configuration options.
+       * man/amanda.8.in: Document it.
+       * example/amanda.conf.in: Document it.
+       * server-src/holding.h (get_flush, pick_datestamp, pick_all_datestamp,
+       cleanup_holdingdisk): New prototype.
+       * server-src/holding.c (scan_holdingdir, cleanup_holdingdisk,
+       get_flush): New function.
+       * server-src/holding.c (pick_datestamp, pick_all_datestamp): New
+       verbose argument.
+       * server-src/amcleanupdisk.c: Change call to pick_all_datestamp.
+       * server-src/amflush.c: Change call to pick_all_datestamp.
+       * server-src/find.c: Change call to pick_all_datestamp.
+       * server-src/planner.c: Write FLUSH line to driver, the schedule
+       line contain the keyword DUMP.
+       * server-src/planner.c: Add datestamp to SUCCESS and FAIL line.
+       * server-src/amstatus.pl.in: New parsing of DUMP line.
+       * server-src/driverio.h: New datestamp field in sched_t;
+       * server-src/driver.c (build_diskspace): New function to build a
+       assignedhd_t from an holding file.
+       * server-src/driver.c (read_flush): New function to read the list
+       of files to flush.
+       * server-src/driver.c (read_schedule): Parse the keyword DUMP.
+       * server-src/driver.c: Add datestamp to FAIL line.
+       * server-src/dumper.c: Add datestamp to FAIL line.
+       * server-src/reporter.c (timedata_t, repdata_t) : Major change of
+       structure.
+       * server-src/taper.c: Add datestamp to FAIL line.
+
+2001-11-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.c: New dumporder configuration.
+       * server-src/conffile.h: Likewise.
+       * server-src/driver.c (start_some_dumps): Use dumporder to
+       select the next disk to dump.
+       * example/amanda.conf.in: Give an example of dumporder.
+       * man/amanda.8.in: Document it.
+
+2001-11-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/amrecover.h (cd_glob, cd_regex, cd_dir): New prototypes.
+       * recover-src/set_commands.c (cd_glob, cd_regex, cd_dir): New functions.
+       * recover-src/uparse.y: Add new token CDX, call cd_glob instead
+       of set_directory for cd command, call cd_regex for cdx command.
+       * recover-src/uscan.l: On cdx string return CDX token.
+       * recover-src/help.c: Document it.
+       * man/amrecover.8.in: Document it.
+
+2001-11-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/taper.c: Backport from 2.5.0 the change to use only
+       one cmd_t type for all program.
+       * server-src/server_util.h: Likewise.
+       * server-src/server_util.c: Likewise.
+       * server-src/dumper.c.orig: Likewise.
+       * server-src/dumper.c: Likewise.
+       * server-src/driverio.h: Likewise.
+       * server-src/driverio.c: Likewise.
+       * server-src/driver.c: Likewise.
+       * server-src/amflush.c: Likewise.
+
+2001-11-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: Backport from 2.5.0 the change to allow
+       the "[host [disk]*]*" arguments on command.
+       * server-src/planner.c: Likewise.
+       * server-src/logfile.h: Likewise.
+       * server-src/logfile.c: Likewise.
+       * server-src/find.h: Likewise.
+       * server-src/find.c: Likewise.
+       * server-src/diskfile.h: Likewise.
+       * server-src/diskfile.c: Likewise.
+       * server-src/amtrmidx.c: Likewise.
+       * server-src/amindexd.c: Likewise.
+       * server-src/amflush.c: Likewise.
+       * server-src/amdump.sh.in: Likewise.
+       * server-src/amcheck.c: Likewise.
+       * server-src/amadmin.c: Likewise.
+       * restore-src/amrestore.c: Likewise.
+       * man/amrestore.8: Likewise.
+       * man/amflush.8.in: Likewise.
+       * man/amdump.8.in: Likewise.
+       * man/amcheck.8.in: Likewise.
+       * man/amanda.8.in: Likewise.
+       * man/amadmin.8.in: Likewise.
+       * common-src/match.c: Likewise.
+       * common-src/amanda.h: Likewise.
+
+2001-10-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/Makefile.am: add amdd.8 and ammt.8 to EXTRA_DIST.
+
+2001-09-26 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/reporter.c: Fix problem when column sizes are negative.
+
+2001-09-21 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/Makefile.am: Add -I../common-src so genversion.h can be
+         found (since it is built on the fly).  Only fails when build is done
+         in a different directory than the sources.
+
+2001-09-17 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/getconf.c: Add capabilities to amgetconf to return
+         build environment values and also to open and close a debug file
+         (e.g. for scripts).
+       * man/amgetconf.8.in: Ditto.
+       * changer-src/chg-scsi.c: Ditto.
+       * common-src/amanda.h: Ditto.
+       * common-src/debug.c: Ditto.
+       * common-src/error.c: Ditto.
+       * server-src/dumper.c: Ditto.
+
+2001-09-17 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/planner.c: Make sure we do not attempt to bump beyond
+         level 9.
+
+2001-09-15 Thomas Hepper (th@ant.han.de)
+       * changer-src/chg-scsi.c: Added new config option autoinv, 
+       if not set no auto inventory will be done if the label db is out of 
+       sync. Reworked MapBarCode, now the parameters are passed as a struct 
+       and the result is returned in this struct (MBC_T), 
+       also removed some duplicate/nonsens code from MapBarCode
+       Changed the definitions for slot_file. It was used duplicate, 
+       1. as the config file set by amanda.conf, and second set by the
+       config option in the chg-scsi config file. Now the file from
+       amanda.conf is called chg_scsi_conf. and changer_file is renamed 
+       to slot_file.
+       Added check if cleanfile is not set, if true clean_file is set to NULL
+       Now return if tape_device is not in the range 0-9.
+       Added some checks if we have all informations like slot_file, 
+       devices etc. Fixed and error in the search function, 
+       if the searched vol is already loaded return the correct info 
+       and not 'label not found'. Fixed error in the parameter passing 
+       to get_relative_slot. If the option was -slot last we where 
+       1 above the end parameter..
+
+       * changer-src/scsi-bsd.c: Fix compile problems.
+       * changer-src/scsi-changer-driver.c: Fixed the last problems :-) 
+       for the label/barcode handling...
+       * changer-src/scsi-defs.h: Added new struct MBC_T
+       * changer-src/sense.c: Added some more messages for Exabyte 210 lib
+
+2001-09-01 John R. Jackson (jrj@purdue.edu)
+
+       * client-src/sendsize.c: Fix memory allocation problem.
+
+2001-08-31 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/amindex.c: Fix memory leak.  Compliments of Robert Minsk
+         <egbert@centropolisfx.com>.
+       * server-src/logfile.c: Fix memory leak.  Compliments of Robert Minsk
+         <egbert@centropolisfx.com>.
+
+2001-08-30 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/planner.c: Fix problem with maintenance of total level
+         0 size when disk being brought back into the schedule was not doing
+         a level 0.  Compliments of Robert Minsk <egbert@centropolisfx.com>.
+
+2001-08-24 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/amverify.sh.in: Fix missing backtick error.
+
+2001-08-24 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/taper.c: Allocate buffers on page boundaries.
+
+2001-08-22 John R. Jackson (jrj@purdue.edu)
+
+       * tape-src/Makefile.am: Add chown/chgrp rules for ammt/amdd install
+         so they end up like all the other Amanda programs.
+
+2001-08-16 John R. Jackson (jrj@purdue.edu)
+
+       * docs/Makefile.am: Fix PORTS.USAGE -> PORT.USAGE typo.
+
+2001-08-16 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Change release name to "2.4.2p2-tapeio".  Add missing
+         CAM header checks from the 2.5 branch.
+
+2001-08-15 Thomas Hepper (th@ant.han.de)
+       * changer-src/chg-scsi.c. Removed version 1 DB support from mapBarCode. Changed the way parameter
+       are given to MapBarCode and returned from there. No a struct is passed where all infos
+       will be returned to the calling function.
+       If eject is set we will not call LogSense in chg-scsi because it is also called in the
+       eject function.
+       * changer-src/scsi-defs.h: Added struct MBC_T used by MapBarCode.
+       * changer-src/scsi-changer-driver.c: Changed all calls to MapBarCode to the new way
+
+2001-08-14 John R. Jackson (jrj@purdue.edu)
+
+       * docs/EXCLUDE: New document from Andrew Hall <ahall@secureworks.net>
+         describing how to set up and use GNU tar exclusions.
+       * docs/Makefile.am: Added EXCLUDE and PORT.USAGE.
+
+2001-08-14 John R. Jackson (jrj@purdue.edu)
+
+       * docs/PORT.USAGE: New document about how Amanda ports are used.
+
+2001-08-14 John R. Jackson (jrj@purdue.edu)
+
+       * common-src/stream.c: Add stream_client_privileged() function to
+         get a privileged port and fail if one is not available.  The older
+         stream_client() function gets a (non-privileged) port in the
+         configured portrange, if set and possible, else anything available.
+       * common-src/stream.h: Prototypes.
+       * recover-src/amrecover.c: Use stream_client_privileged() instead of
+         stream_client().
+       * recover-src/extract_list.c: Ditto.
+       * configure.in: Added several more port range sanity checks.  Added
+         --with-tcpportrange as an alias for --with-portrange.
+
+2001-08-09 Thomas Hepper (th@ant.han.de)
+       * changer-src/chg-scsi.c: Added check in MapBarCode if the labelfile
+       parameter is empty, and if yes return. 
+       Added global variable do_inventory, and if set do an inventory before
+       exit.
+       In MapBarCode changed the way the UPDATE_SLOT is done, now it uses
+       the slot number passed to MapBarCode to find and update the record.
+       * changer-src/scsi-changer-driver.c: Added def. for BreeceHill Q7
+       Added global variables which are set by the tape_rdlabel function
+       in eject/unload.
+       Reworked the way how the updates of the labelfile are done.
+       * docs/TAPE.CHANGERS: Added note about solaris 8 and the sgen driver.
+
+2001-08-09 John R. Jackson (jrj@purdue.edu)
+
+       * tape-src/output-tape.c: Missed a reference to TAPE_BLOCK_BYTES
+         while doing the tapetype "blocksize" changes.
+
+2001-08-01 John R. Jackson (jrj@purdue.edu)
+
+       * client-src/selfcheck.c: Fix typos I introduced into the PC subdir
+         patch.
+       * client-src/sendbackup-gnutar.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+
+2001-08-01 Marko Injac <marko.injac@mail.insert.si> via John R. Jackson (jrj@purdue.edu)
+
+       * client-src/findpass.c: Allow backup of subdirs of PC shares for
+         amanda-2.4.1beta1 by Greg Shebert amanda-hackers list Tue Feb 1,
+         2000.  Ported to amanda-2.4.2p2 on debian potato by Marko Injac.
+       * client-src/findpass.h: Ditto.
+       * client-src/selfcheck.c: Ditto.
+       * client-src/sendbackup-gnutar.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+       * docs/SAMBA: Ditto.
+
+2001-08-01 John R. Jackson (jrj@purdue.edu)
+
+       * client-src/sendsize.c: Prefix each debug line with sendsize process
+         information to make picking out the output from a particular estimate
+         run easier when maxdumps > 1.
+
+2001-08-01 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/amcheck.c: Unlink the temp files as soon as they are
+         created so they always go away when amcheck terminates.  Use
+         pipespawn() instead of system() to call the MAILER program.
+
+2001-08-01 John R. Jackson (jrj@purdue.edu)
+
+       * common-src/debug.c: Only rename files that end in ".debug".
+
+2001-08-01 John R. Jackson (jrj@purdue.edu)
+
+       * common-src/pipespawn.c: Show empty pipespawn() args as "".
+
+2001-07-31 John R. Jackson (jrj@purdue.edu)
+
+       * server-src/conffile.h: Add support for tapetype "blocksize" keyword.
+       * server-src/conffile.c: Add tapetype "blocksize" keyword.  Use
+         DISK_BLOCK_KB where appropriate instead of TAPE_BLOCK_SIZE.  Disallow
+         negative tape length and tapemark size.
+       * client-src/sendbackup.c: Use new STREAM_BUFSIZE constant.  Use -1
+         for new default buffer size flag.
+       * common-src/alloc.c: Add new amtable_free() function.  Adjust args
+         to amtable_alloc() to be consistent with amtable_free().
+       * common-src/amanda.h: Add new am_round() and am_floor() macros.
+         Define new DISK_BLOCK_KB, DISK_BLOCK_BYTES, MAX_TAPE_BLOCK_KB,
+         MAX_TAPE_BLOCK_BYTES constants.  Remove TAPE_BLOCK_SIZE and
+         TAPE_BLOCK_BYTES.
+       * common-src/fileheader.c: Change write_header() to build_header().
+         Add blocksize arg.  Get rid of unused fill_buffer() function.
+       * common-src/fileheader.h: Ditto.
+       * common-src/stream.c: Use negative value to indicate default buffer
+         size.
+       * common-src/stream.h: Add NETWORK_BLOCK_BYTES and STREAM_BUFSIZE
+         constants.  Remove DATABUF_SIZE and DEFAULT_SIZE.
+       * man/amanda.8.in: Document the new "blocksize" tapetype keyword.
+         Document that "length" in tapetype has meaning to some output
+         drivers.  Fix "bumpdays" and "speed" defaults.  Document new "file:"
+         output driver record length data file.
+       * man/amrestore.8: Add new "-b blocksize" arg.  Add description of
+         how to catalogue the images on a tape.
+       * recover-src/amrecover.c: DEFAULT_SIZE -> -1.
+       * recover-src/extract_list.c: DEFAULT_SIZE -> -1.  Use DISK_BLOCK_BYTES
+         instead of TAPE_BLOCK_BYTES for the header size.
+       * restore-src/amrestore.c: Add new "-b blocksize" arg.  Document how
+         the header is handled.  Deal with arbritrary tape record sizes.
+       * server-src/amlabel.c: Use the tapetype blocksize.
+       * server-src/driver.c: Use DISK_BLOCK_KB where appropriate instead of
+         TAPE_BLOCK_SIZE.
+       * server-src/dumper.c: Use DISK_BLOCK_BYTES and DISK_BLOCK_KB as
+         appropropriate instead of older constants.  Rewrite disk I/O buffer
+         management.  Never pad output stream (e.g. to holding disk).  Use
+         -1 for default stream buffer size.
+       * server-src/holding.c: Change TAPE_BLOCK_BYTES to DISK_BLOCK_BYTES.
+         Use fullread() instead of fill_buffer().
+       * server-src/planner.c: Use tapetype blocksize instead of constant
+         for tape length calculations.
+       * server-src/taper.c: Support tapetype blocksize.  Only pad writes if
+         blocksize is negative.  Reorganize shared memory buffers to put
+         data on page boundaries.  Try reducing tapebuf count if allocation
+         fails.
+       * tape-src/output-file.c: Maintain record size information.  Use mask
+         and flags from caller.
+       * tape-src/output-null.c: Use new amtable_alloc() arg order.
+       * tape-src/output-rait.c: Use new amtable_alloc() arg order.  Add
+         private version of amtable_free() for standalone build.  Fix off
+         by one and other table allocation problems.
+       * tape-src/output-rait.h: Maintain file descriptor count in the
+         structure.
+       * tape-src/tapeio.c: Support tapetype blocksize.  Use new
+         amtable_alloc() arg order.  Fix some error message text.  
+       * tape-src/tapeio.h: New prototypes with blocksize arg.
+       * tape-src/tapetype.c: Add "-b blocksize" arg.  Fix some end case
+         aborts.
+
+2001-07-31 Ben Lewis (bhlewis@purdue.edu) via John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Add missing CAM header checks from the 2.5 branch.
+
+2001-07-30 John R. Jackson (jrj@purdue.edu)
+
+       * configure.in: Add CAM SCSI support section from the 2.5 branch.
+
+2001-07-30 Ben Lewis (bhlewis@purdue.edu) via John R. Jackson (jrj@purdue.edu)
+
+       * recover-src/amrecover.c: Improve the "Unexpected server end of file"
+         message.
+
+2001-07-30 Ben Lewis (bhlewis@purdue.edu) via John R. Jackson (jrj@purdue.edu)
+
+       * man/amanda.8.in: Document includefile.
+       * man/amdump.8.in: Add note that local crontab documention should be
+         checked for proper syntax.
+       * man/amrecover.8.in: Document use of PAGER environment variable.
+       * man/amrestore.8: Document that GNU tar must be used as some vendor
+         tar programs cannot read GNU tar format.
+       * docs/FAQ: Update location of online FAQ.
+
+2001-07-25 John R. Jackson <jrj@purdue.edu>
+
+       * docs/TAPE.CHANGER: Changes from Ben Lewis (bhlewis@purdue.edu) to
+         document the new (but optional) searchable features.
+
+2001-07-20 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/security.c: Use NUM_STR_SIZE instead of hard coded
+         constant.
+       * common-src/versuff.c.in: Ditto.
+
+2001-07-19 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/error.c: Add new function errordump() that acts like
+         error() but calls abort() to (try to) drop core.
+       * common-src/amanda.h: Prototype.
+       * common-src/alloc.c: Call errordump() instead of error() for some
+         memory allocation failures to aid traceback.
+
+2001-07-19 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amadmin.c: Improve the error message when read_conffile()
+         fails.
+       * server-src/amcheck.c: Ditto.
+       * server-src/amcleanupdisk.c: Ditto.
+       * server-src/amflush.c: Ditto.
+       * server-src/amlabel.c: Ditto.
+       * server-src/amlogroll.c: Ditto.
+       * server-src/amtape.c: Ditto.
+       * server-src/amtrmidx.c: Ditto.
+       * server-src/amtrmlog.c: Ditto.
+       * server-src/driver.c: Ditto.
+       * server-src/dumper.c: Ditto.
+       * server-src/getconf.c: Ditto.
+       * server-src/planner.c: Ditto.
+       * server-src/reporter.c: Ditto.
+       * server-src/taper.c: Ditto.
+
+2001-07-19 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/driverio.c: Make the name "ps" reports match the dumper
+         name (e.g. "dumper3").
+
+2001-07-18 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/chg-chio.pl.in: Try to unload the drive before moving
+         a tape back to a slot.  Fixes a problem on Ecrix AutoPAK devices.
+         Patch compliments of Sam Leffler <sam@errno.com>.
+
+2001-07-18 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: Change to the Amanda temp directory
+         instead of the config directory.  In addition to making amverify
+         act like most other Amanda programs, this gets around an
+         xfsrestore bug.
+
+2001-07-18 John R. Jackson <jrj@purdue.edu>
+
+       * man/amanda.8.in: Describe the .amandahosts format better.  Clean up
+         a couple of minor typos.
+
+2001-07-13 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/dgram.h: Improve UDP datagram size calculation.
+       * server-src/amcheck.c: Break up large requests into pieces.
+       * server-src/planner.c: Break up large requests into pieces.
+
+2001-07-12 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/amdd.c: Use tapefd_close() in amdd if the file was
+         opened with tape_open().  This does any necessary output driver
+         cleanup (such as moving the current file position for "file:").
+
+2001-07-12 John R. Jackson <jrj@purdue.edu>
+
+       * Makefile.am: Fix automake warning.
+
+2001-07-11 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/tapetype.c: Use tapefd_write() instead of write().
+
+2001-07-11 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/file.c: Fix a memory leak.  Grab exponentially larger
+         chunks of memory up to a point, then level out.
+
+2001-07-11 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/tapetype.c: Only report a pass summary when stderr is not
+         a tty.  Deal with some obscure end cases.
+
+2001-07-10 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/Makefile.am: Backport development branch chg-scsi code
+         to 2.4.2.
+       * changer-src/chg-scsi.c: Ditto.
+       * changer-src/libscsi.h: Ditto.
+       * changer-src/scsi-aix.c: Ditto.
+       * changer-src/scsi-bsd.c: Ditto.
+       * changer-src/scsi-cam.c: Ditto.
+       * changer-src/scsi-changer-driver.c: Ditto.
+       * changer-src/scsi-defs.h: Ditto.
+       * changer-src/scsi-hpux.c: Ditto.
+       * changer-src/scsi-hpux_new.c: Ditto.
+       * changer-src/scsi-irix.c: Ditto.
+       * changer-src/scsi-linux.c: Ditto.
+       * changer-src/scsi-solaris.c: Ditto.
+       * changer-src/sense.c: Ditto.
+
+2001-07-10 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amcheck.c: Move user name check before attempt to create
+         temp files so more appropriate error message is generated.
+
+2001-07-09 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/dgram.c: Fix error end case unitialized variable.
+
+2001-07-05 John R. Jackson <jrj@purdue.edu>
+
+       * docs/TAPE.CHANGERS: Minor docs/TAPE.CHANGERS update to clarify
+         that -slot and -eject unload and put the current tape away.
+
+2001-07-02 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/chg-manual.sh.in: Add yet another ONLINEREGEX, this one
+         compliments of Nick (n_hibma@qubesoft.com) for some FreeBSD variant.
+
+2001-06-29 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/tapeio.c: Move the device name parsing routines from the
+         RAIT module to tapeio and make them generic.  This allows one
+         module to open another, e.g. rait:{null:,z1,z2,z3}.  Maintain
+         both the original open flags and mask and use them on the real open.
+       * tape-src/amdd.c: Make sure this compiles "stand-alone".  To do so,
+         use: gcc -Wall -DNO_AMANDA amdd.c output-rait.c output-tape.c.
+         Abort as soon as one of the open calls fails instead of waiting
+         for read/write to report a bad file descriptor.
+         Pass a mask to the open function in case the output is created.
+       * tape-src/ammt.c: Make sure this compiles "stand-alone".  To do so,
+         use: gcc -Wall -DNO_AMANDA ammt.c output-rait.c output-tape.c.
+       * tape-src/output-file.c: Maintain both the original open flags and
+         mask and use them on the real open.
+       * tape-src/output-null.c: Ditto.
+       * tape-src/output-file.h: Change to non-prototype declaration of
+         file_tape_open() to deal with the optional mask parameter.
+       * tape-src/output-null.h: Ditto.
+       * tape-src/output-tape.h: Ditto.
+       * tape-src/tapeio.h: Ditto.  Add device name parsing prototypes.
+       * tape-src/output-rait.c: Make sure this compiles "stand-alone".
+         Maintain both the original open flags and mask and use them on the
+         real open.
+       * tape-src/output-rait.h: Make sure this compiles "stand-alone".
+       * tape-src/output-tape.c: Make this part of the "stand-alone" compile
+         of ammt and amdd since it knows all the proper ioctl operations.
+         Maintain both the original open flags and mask and use them on the
+         real open.
+
+2001-06-27 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/chg-manual.sh.in: Add "bs=32k" to the dd command so
+         some kernels would not complain about the tape block being larger
+         than the buffer.
+       * changer-src/chg-mtx.sh.in: Ditto.
+
+2001-06-21 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/planner.c: If the compression rate is very small (such
+         as zero after some types of errors) and FORCE_FULL is set, a path
+         is taken that (among other bad things) generates a schedule that
+         driver cannot read (syntax errors).
+       * server-src/conffile.c: Do not allow negative comprate values.
+
+2001-06-19 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/holding.c: Use fullread() instead of read() to read the
+         holding disk file.
+
+2001-06-19 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amtape.c: Document "slot advance" in the help output.
+
+2001-06-19 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amindexd.c: Minor gethostbyaddr() argument change to be
+         consistent with other Amanda usage.
+
+2001-06-19 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: Better cross platform tar detection.
+
+2001-06-19 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: More of the vrestore vs. 'b' flag change.
+
+2001-06-19 John R. Jackson <jrj@purdue.edu>
+
+       * recover-src/amrecover.c: Add more debugging to guess_disk()
+         function to better track how the disk is determined from the
+         current working directory.  Report current working directory in
+         error message.  Change "Trying" to "Trying disk" to distinguish
+         this from host attempts.
+       * recover-src/set_commands.c: Remove redundant amfree() call.  Remove
+         redundant "OISD /" exchange.  Change "Trying" to "Trying host" to
+         distinguish this from disk attempts.
+
+2001-06-18 John R. Jackson <jrj@purdue.edu>
+
+       * recover-src/extract_list.c: Do not pass a 'b' (blocking) factor
+         flag to vrestore.  Some versions do not like it.
+
+2001-06-18 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/dgram.c: Use a sin_addr arg to inet_ntoa() like all the
+         other Amanda code.
+       * common-src/stream.c: Ditto.
+
+2001-06-18 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/chg-manual.sh.in: Add yet another online regex.  Found
+         by George Herson <gherson@snet.net>.
+
+2001-06-01 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amindexd.c (build_disk_table): Make sure a holding disk
+         image is used rather than a copy also on tape, if both exist.
+
+2001-05-29 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/reporter.c: Fix PostScript output to only show what went
+         on the tape, not what the total amount dumped.  Compliments of
+         Joshua Baker-LePain <jlb17@duke.edu>.
+
+2001-05-18 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/patch-system.sh.in: Missed a reference to kamanda in the
+         last patch.  Compliments of Tom Schutter <t.schutter@att.net>.
+
+2001-05-16 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/patch-system.sh.in: Go ahead and update /etc/services
+         on a client even if the services themselves are not turned on to
+         inetd.  Compliments of Tom Schutter <t.schutter@att.net>.  Add
+         the TCP port for amandad for future use.
+
+2001-05-15 John R. Jackson <jrj@purdue.edu>
+
+       * restore-src/amidxtaped.c: Call tape_stat() instead of stat() to
+         decide if an image is a file or a tape.
+
+2001-05-14 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/amandad.c: Fix hang when the incoming packet size is
+         larger than the pipe buffer.  Also fix a buffer overflow bug.
+
+2001-05-11 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/chg-scsi.c: Add support for "-slot advance".
+
+2001-05-11 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/util.c (bind_portrange): Log a debug message stating
+         explicitly that all ports in the requested range were busy, or
+         that a specific port failed bind() for an unexpected reason.
+
+2001-05-11 John R. Jackson <jrj@purdue.edu>
+
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.2p2)
+
+2001-05-10 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/scsi-changer-driver.c: Fix routine name in diagnostic
+         messages for DLT4000Eject.
+
+2001-05-07 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/sendbackup-dump.c: Do not use full path to sed.  Found by
+         Roland E. Lipovits (rel@lipo.at0.net).
+
+2001-05-04 John R. Jackson <jrj@purdue.edu>
+
+       * config/depcomp: Fix problem with argument processing and update to
+         latest version.
+
+2001-04-25 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/chg-rth.pl.in: Add exec_prefix back since it is usually
+         used to define sbindir.  Sigh.  Include X=X assignments to get rid
+         of the Perl warnings.
+       * server-src/amoverview.pl.in: Ditto.
+
+2001-04-24 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/chg-chio.pl.in: Remove unused exec_prefix to get rid of
+         warning message.  Patch from Nick Hibma <n_hibma@qubesoft.com>.
+
+2001-04-23 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/selfcheck.c: Allow Samba shares with no password.
+       * client-src/sendbackup-gnutar.c: Ditto.
+       * client-src/sendsize.c: Ditto.
+
+2001-04-21 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/output-tape.c: Fix IRIX field reference (patch from Marc
+         W. Mengel <mengel@fnal.gov>).
+
+2001-04-13 John R. Jackson <jrj@purdue.edu>
+
+       * example/amanda.conf.in: Fix multiple holding disks comment.
+       * example/amanda.conf.chg-scsi.in: Ditto, plus bring this file into
+         sync with the base version.
+
+2001-04-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/getfsent.h (search_fstab): New prototype.
+       * client-src/getfsent.c (search_fstab): New arg check_dev, skip
+       entry if check_dev==1 and device stats failed.
+       * client-src/getfsent.c (open_fstab for linux): Open MOUNTED.
+       * client-src/getfsent.c (close_fstab for linux): close MOUNTED.
+       * client-src/getfsent.c (get_fstab_nextentry for linux): parse MOUNTED.
+       * client-src/getfsent.c (amname_to_devname, amname_to_dirname,
+       amname_to_fstype): Call search_fstab sequentialy with 1 and 0
+       for check_dev.
+
+2001-04-10 John R. Jackson <jrj@purdue.edu>
+
+       * docs/INSTALL: Update location to GNUPLOT per Lars Hecking
+         <lhecking@nmrc.ie>.
+
+2001-04-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * config/config.guess: Upgrade from ftp://ftp.gnu.org/pub/gnu/config
+       * config/config.sub: Upgrade from ftp://ftp.gnu.org/pub/gnu/config
+       * config/mkinstalldirs: Upgrade from automake CVS.
+
+2001-04-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * config/depcomp: new file for automake.
+
+2001-04-03 John R. Jackson <jrj@purdue.edu>
+
+       * Makefile.am: Remove *.test.c from the distribution.
+
+2001-04-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Upgrade to the 2.5.0 code.
+
+       * changer-src/chg-zd-mtx.sh.in: Added barcode reader support,
+       >9 tape slot support, variable for 'offline' or 'ONLINE'
+       return value of tape device, and multi-config support.  Moved
+       all user settable variables to 'changerfile'.conf in the
+       amanda config directory.  Added commented out example of .conf
+       file into script.
+       * NEWS: updated chg-zd-mtx.sh.in changer.
+
+2001-04-02 John R. Jackson <jrj@purdue.edu>
+
+       * NEWS: Initial notes for 2.4.2p2.
+
+2001-03-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/getfsent.c (search_fstab): If the device doesn't 
+       exist, it will take the entry from /etc/mtab.
+
+2001-03-26 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amtape.c: Do not rewind for slot "advance".  Do not report
+         device name (which is bogus) for slot "advance".
+
+2001-03-23 John R. Jackson <jrj@purdue.edu>
+
+       * example/amanda.conf.in: Add warning that the sample amanda.conf
+         will not work as is and must be edited to match the installation.
+
+2001-03-21 John R. Jackson <jrj@purdue.edu>
+
+       * recover-src/extract_list.c (extract_files_child): Fix problem that
+         caused xfsrestore arg list to not be NULL terminated.
+
+2001-03-19 John R. Jackson <jrj@purdue.edu>
+
+       * configure.in: Add --with-debug-days (default is 4) and remove
+         --with-pid-debug-files.
+       * common-src/Makefile.am: Clean up test program dependencies.
+       * common-src/debug.c: Create timestamped debug file names and remove
+         files older (based on file name) than --with-debug-days.  Rename old
+         style names to new style (based on modification time) the first time
+         they are seen.
+       * common-src/file.c: Use construct_datestamp() instead of private code.
+       * common-src/genversion.c: Display AMANDA_DEBUG_DAYS and remove
+         DEBUG_FILE_WITH_PID.
+       * common-src/util.c: Move construct_datestamp to here and add new
+         function construct_timestamp.  Change time used to build string to
+         be an optional parameter instead of always getting it in the routine.
+       * common-src/util.h: Add prototypes.
+       * server-src/amcleanupdisk.c: Change construct_datestamp call to pass
+         indication that it should get the current time.
+       * server-src/amflush.c: Ditto.
+       * server-src/driver.c: Ditto.
+       * server-src/dumper.c: Ditto.
+       * server-src/planner.c: Ditto.
+       * server-src/server_util.c: Remove construct_datestamp (now in util.c).
+       * server-src/server_util.h: Remove prototype.
+
+2001-03-15 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/planner.c (analyze_estimate): Do not do an incremental
+         if FORCE_NO_BUMP is set and the last dump was a level 0.
+
+2001-03-14 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amcheck.c: Change message from NOTE to WARNING when
+         the hold file exists.
+       * man/amcheck.8.in: Ditto.
+
+2001-03-14 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/selfcheck.c: Send smbclient via pipe instead of command
+         line arg.  Various minor cleanups.  Use pipespawn instead of system()
+         to clean up quoting problems and be consistent with sendsize and
+         sendbackup.
+       * client-src/sendbackup-dump.c: Send smbclient via pipe instead of
+         line arg.  Various minor cleanups.
+       * client-src/sendbackup-gnutar.c: Send smbclient via pipe instead of
+         line arg.  Various minor cleanups.  Clean up listed incremental file
+         handling.
+       * client-src/sendbackup.c: Various minor cleanups.
+       * client-src/sendsize.c: Send smbclient via pipe instead of command
+         line arg.  Various minor cleanups.  Clean up listed incremental file
+         handling.
+       * common-src/pipespawn.c: Support optional password pipe.  Various
+         minor cleanups.
+       * common-src/pipespawn.h: Support optional password pipe.  Various
+         minor cleanups.
+       * common-src/util.c: Backport fullread() and fullwrite() from main
+         branch.
+       * common-src/util.h: Backport fullread() and fullwrite() from main
+         branch.
+       * docs/SAMBA: Update and cleanup.
+
+2001-03-13 John R. Jackson <jrj@purdue.edu>
+
+       * recover-src/extract_list.c (extract_files_child): Fix xfsrestore
+         argument list processing.
+
+2001-03-09 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/taper.c: Initialize tape_fd to -1 and test in a couple
+         more places.  Run normal protocol after a tape startup error (e.g.
+         "cannot overwrite") instead of just exiting to keep driver from
+         reporting a broken pipe.
+
+2001-03-08  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Reported by Eric Schnoebelen <eric@cirr.com>
+
+       * server-src/changer.c (): Fix fd leak.
+
+2001-02-28  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (info_one): typo.
+       * server-src/planner.c (setup_estimate): Don't re-ask for level 0
+       if last_level is 0 and FORCE_NO_BUMP is set.
+
+2001-02-27 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/stream.h: Move DATABUF_SIZE to stream.h.
+       * client-src/sendbackup.c: Do not ask for a big receive buffer.
+       * server-src/dumper.c: Ask for a bigger send buffer.  Minor typos.
+       * server-src/taper.c: Ask for a bigger receive buffer.
+       * recover-src/amrecover.c: Use stream_client instead of specific
+         (and incorrect) bind() code.
+       * recover-src/extract_list.c: Ditto.
+
+2001-02-27 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/dgram.c: Add lots more error logging to help track down
+         problems.
+
+2001-02-27 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/stream.c: Add lots more error logging to help track down
+         problems.
+
+2001-02-27 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/amtape.c: Rewind after loading a slot either by slot
+         or by label.
+
+2001-02-27 John R. Jackson <jrj@purdue.edu>
+
+       * configure.in: Copy ssize_t type check code from main branch.
+
+2001-02-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/SYSTEM.NOTES: change cs.umd.edu by amanda.org.
+
+2001-02-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amindexd.c (uncompress_file): remove uncompressed
+       index file if the command failed.
+
+2001-02-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/scsi-changer-driver.c (GenericRewind): init ret to 0
+       to remove compiler warning.
+
+2001-02-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (setup_estimate): ask for level 0 for
+       a new disk if force-bump is set,
+       log force-bump and force-nobump command.
+
+2001-02-21 Thomas Hepper <thqant.han.de>
+       * changer-src/scsi-changer-driver.c: Do an Test Unit Ready
+         before sending SCSI commands in GenericRewind
+       * changer-src/chg-scsi.c: Fixed an type in the debug print
+         of the config file
+
+2001-02-09 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/diskfile.c: Fix core dump in test program.
+
+2001-02-09 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/output-file.c: Use a "data" subdirectory of the main
+         file driver device directory to hold the tape "files".  This
+         allows the status file to be moved to the main directory.
+       * man/amanda.8.in: Document these changes.
+
+2001-02-05 John R. Jackson <jrj@purdue.edu>
+
+       * man/amanda.8.in: Fix mailto to space separated, not comma.
+
+2001-02-03 John R. Jackson <jrj@purdue.edu>
+
+       * .cvsignore: Add entries to keep CVS quiet.
+       * */.cvsignore: Ditto.
+
+2001-02-03 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/Makefile.am: Add CLEANFILES rule to remove *.test.c.
+       * common-src/Makefile.am: Add more sources as needed to the test
+         programs so they would compile.
+       * server-src/Makefile.am: Create TEST_PROGS make variable ala the
+         other Makefile.am files.
+       * tape-src/Makefile.am: Add CLEANFILES rule to remove *.test.c.
+
+2001-02-02 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/reporter.c: Fix problem with enum being unsigned on
+         some systems.
+
+2001-01-29 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/output-tape.c (tape_tapefd_status): Convert flag values
+         to booleans (compliments of Marc W. Mengel <mengel@fnal.gov>).
+       * tape-src/tapeio.c (tape_fsf): Use ap_snprintf instead of snprintf
+         (also compliments of Marc).
+
+2001-01-26 John R. Jackson <jrj@purdue.edu>
+
+       * changer-src/Makefile.am: Double up the references to libamanda to
+         handle systems that put regex in strange places.
+       * client-src/Makefile.am: Ditto.
+       * recover-src/Makefile.am: Ditto.
+       * restore-src/Makefile.am: Ditto.
+       * server-src/Makefile.am: Ditto.
+       * tape-src/Makefile.am: Ditto.
+
+2001-01-24 John R. Jackson <jrj@purdue.edu>
+
+       * docs/VTAPE-API: Added.
+
+2001-01-23 John R. Jackson <jrj@purdue.edu>
+
+       * configure.in: Add tapeio switch from Marc Mengel <mengel@fnal.gov>,
+         enhance and add "null" and "file" output drivers.  Change all
+         tape changers (except chg-scsi) to use amdd and ammt.  Change all
+         tape changers (except chg-scsi) to log and use a consistent
+         error reporting scheme.  Fix various bugs along the way.  Add new
+         chg-multi config option, posteject, which is an optional script
+         to call after each "tape" is ejected (e.g. to use to start a
+         CDROM writer).  Remove special code for tapedev of /dev/null
+         (now handled by the "null" output driver).  Changed the taper
+         protocol to pass the host/disk/level so the write can send that
+         along to the output driver.  Fairly major rework of amrestore
+         to clean up tape/non-tape and other oddities.
+       * changer-src/chg-chio.pl.in: Ditto.
+       * changer-src/chg-chs.sh.in: Ditto.
+       * changer-src/chg-manual.sh.in: Ditto.
+       * changer-src/chg-mtx.sh.in: Ditto.
+       * changer-src/chg-multi.sh.in: Ditto.
+       * changer-src/chg-rth.pl.in: Ditto.
+       * changer-src/chg-zd-mtx.sh.in: Ditto.
+       * client-src/sendbackup.c: Ditto.
+       * common-src/alloc.c: Ditto.
+       * common-src/amanda.h: Ditto.
+       * docs/INTERNALS: Ditto.
+       * man/Makefile.am: Ditto.
+       * man/amanda.8.in: Ditto.
+       * man/amdd.8: Ditto.
+       * man/ammt.8: Ditto.
+       * restore-src/amrestore.c: Ditto.
+       * server-src/amcheck.c: Ditto.
+       * server-src/amlabel.c: Ditto.
+       * server-src/amtape.c: Ditto.
+       * server-src/amverify.sh.in: Ditto.
+       * server-src/conffile.c: Ditto.
+       * server-src/conffile.h: Ditto.
+       * server-src/taper.c: Ditto.
+       * tape-src/Makefile.am: Ditto.
+       * tape-src/amdd.c: Ditto.
+       * tape-src/ammt.c: Ditto.
+       * tape-src/output-file.c: Ditto.
+       * tape-src/output-file.h: Ditto.
+       * tape-src/output-null.c: Ditto.
+       * tape-src/output-null.h: Ditto.
+       * tape-src/output-rait.c: Ditto.
+       * tape-src/output-rait.h: Ditto.
+       * tape-src/output-tape.c: Ditto.
+       * tape-src/output-tape.h: Ditto.
+       * tape-src/tapeio.c: Ditto.
+       * tape-src/tapeio.h: Ditto.
+       * tape-src/tests/amtapeio.test.000: Ditto.
+       * tape-src/tests/amtapeio.test.001: Ditto.
+       * tape-src/tests/amtapeio.test.002: Ditto.
+       * tape-src/tests/amtapeio.test.003: Ditto.
+       * tape-src/tests/amtapeio.test.004: Ditto.
+       * tape-src/tests/amtapeio.test.005: Ditto.
+       * tape-src/tests/amtapeio.test.006: Ditto.
+       * tape-src/tests/amtapeio.test.007: Ditto.
+       * tape-src/tests/amtapeio.test.008: Ditto.
+       * tape-src/tests/amtapeio.test.009: Ditto.
+       * tape-src/tests/amtapeio.test.010: Ditto.
+       * tape-src/tests/amtapeio.test.011: Ditto.
+       * tape-src/tests/amtapeio.test.012: Ditto.
+       * tape-src/tests/amtapeio.test.013: Ditto.
+       * tape-src/tests/amtapeio.test.014: Ditto.
+       * tape-src/tests/amtapeio.test.015: Ditto.
+       * tape-src/tests/amtapeio.test.016: Ditto.
+       * tape-src/tests/amtapeio.test.017: Ditto.
+       * tape-src/tests/amtapeio.test.018: Ditto.
+       * tape-src/tests/cleartape: Ditto.
+       * tape-src/tests/newtest: Ditto.
+       * tape-src/tests/rerun: Ditto.
+       * tape-src/tests/runtest: Ditto.
+       * tape-src/tests/testdist: Ditto.
+       * tape-src/tests/torture: Ditto.
+
+2001-01-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h (sched_t): new field no_space.
+       * server-src/driver.c (start_some_dumps): don't start a disk if
+         no_space is set.
+       * server-src/driver.c (continue_dumps): set no_space if it's the
+         only active dumpers, case c.
+       * server-src/driver.c (read_schedule): set no_space to 0.
+
+2001-01-23 John R. Jackson <jrj@purdue.edu>
+
+       * configure.in: Test for setmntent.
+       * client-src/getfsent.c: Add some support for Redhat 7 /etc/fstab
+         changes that indirectly reference the device for a file system.
+
+2001-01-20  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in: AM_INIT_AUTOMAKE(amanda, 2.4.2p1)
+
+2001-01-20  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * NEWS: 2.4.2p1 is a bug fix release.
+
+2001-01-20  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/INSTALL: Notes about tar-1.13.19
+
+2001-01-07  Thomas Hepper <th@ant.han.de>
+
+       * changer-src/chg-scsi.c: Moved defs. for config_t and changer_t
+       into scsi-defs.h
+       New option havebarcode to force the reading of the barcode labels
+       * changer/src/scsi-changer-driver.c: GenericBarCode now returns
+       true/false depending on the setting of havebarcode.
+       Removed EXB230DElementStatus, the exsisting Exabyte function works.
+       Fixed more warnings from -Wshadow
+
+2001-01-04 John R. Jackson <jrj@purdue.edu>
+
+       * common-src/error.c (error): If the debug file pointer is set, log
+         any fatal error message to it and close the file so it has a good
+         trace of what happened and when.
+
+2001-01-04 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/killpgrp.c: Calls to error() do not need a newline.
+
+2001-01-04 John R. Jackson <jrj@purdue.edu>
+
+       * man/amanda.8.in: Try to make it clearer that dumpcycle and maxdumps
+         changes in the main part of the config file must appear before any
+         dumptype definitions, and also that inherited dumptypes must appear
+         before their reference.
+
+2001-01-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (continue_dumps): Don't reduce est_size if
+         it is already larger than holding space allocated.
+       * server-src/dumper.c: Better handling of ENOSPC from open() and
+         write_tapeheader().
+
+2001-01-04 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/conffile.c (main): Fix conffile test program so it builds
+         and works again.
+
+2001-01-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/scsi-defs.h (ChangerCMD_T): replace array function
+         pointer by enumerated pointers.
+       * changer-src/scsi-changer-driver.c: Use new calling convention.
+
+2001-01-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: Better support for TRY-AGAIN and
+         ABORT-FINISHED result.
+
+2001-01-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Andreas F Mueller <afm@othello.ch>
+
+       * server-src/amadmin.c (force_no_bump_one): Fix message.
+
+2000-12-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (analyze_estimate): pick incremental level
+       if no estimate of level 0.
+
+2000-12-24 John R. Jackson <jrj@purdue.edu>
+
+       * server-src/getconf.c: Fix free() of static text string (BUGGY) when
+         the parameter being looked up is bad.
+
+2000-12-23 David Wolfskill  <dhw@whistle.com>
+
+        * server-src/amcheck.c (start_server_check): Change directory
+          writable check to be for the tapelist directory instead of
+         the config file directory.  Remove config file directory test.
+        * man/amcheck.8.in: Add mention of tapelist directory and do
+         some other directory writable cleanup.
+
+2000-12-13 John R. Jackson <jrj@purdue.edu>
+
+       * docs/Makefile.am: Removing entries for missing RAIT/VTAPE-API files.
+
+2000-12-13 John R. Jackson <jrj@purdue.edu>
+
+       * tape-src/tapeio.c: De-commit the RAIT feature from 2.4.2.  It will
+         be in 2.5 and 2.4.2-multitape.
+       * tape-src/tapeio.h: Ditto.
+       * tape-src/Makefile.am: Ditto.
+
+2000-12-12 John R. Jackson <jrj@purdue.edu>
+
+       * client-src/sendbackup-gnutar.c: Fix regex pattern to accept blanks
+         or tabs.
+
+2000-12-12 John R. Jackson  <jrj@purdue.edu> and Marc Mengel <mengel@fnal.gov>
+
+       * Makefile.am: Work around problem with automake 1.4 not including
+         pkgdata_DATA.
+       * docs/RAIT: New file.
+       * docs/VTAPE-API: New file.
+       * docs/Makefile.am: Include RAIT and VTAPE-API in distribution.
+         Work around problem with automake 1.4 not including pkgdata_DATA.
+       * tape-src/output-rait.h: New File providing RAIT virtual tape type.
+       * tape-src/output-rait.c: New File providing RAIT virtual tape type.
+       * tape-src/Makefile.am: Add output-rait.c.
+       * tape-src/tapeio.c: Major Surgery.
+         (vtable): New static table of virtual tape types.
+         (fdtable): New static table mapping file descriptors.
+         (tapefd_fsf_ioctl): Renamed tapefd_fsf, with added ioctl argument.
+         (tapefd_rewind_ioctl): Likewise.
+         (tapefd_unload_ioctl): Likewise.
+         (tapefd_weof_ioctl): Likewise.
+         (tapefd_status_ioctl): Likewise.
+         (tape_open): Now is a virtual tape table lookup and call.
+         (tape_access): Now is a switch through virtual tape table.
+         (tape_stat): Likewise.
+         (tapefd_close): Likewise.
+         (tapefd_fsf): Likewise.
+         (tapefd_read): Likewise.
+         (tapefd_rewind): Likewise.
+         (tapefd_resetofs): Likewise.
+         (tapefd_unload): Likewise.
+         (tapefd_status): Likewise.
+         (tapefd_weof): Likewise.
+         (tapefd_write): Likewise.
+         (plain_tape_access): Rename of tape_access.
+         (plain_tape_open): Likewise.
+         (plain_tapefd_read): Likewise.
+         (plain_tape_stat): Likewise.
+         (plain_tapefd_write): Likewise.
+         (plain_tapefd_close): Likewise.
+         (plain_tapefd_fsf): Now calls tapefd_fsf_ioctl with &ioctl().
+         (plain_tapefd_rewind): Likewise.
+         (plain_tapefd_resetofs): Likewise.
+         (plain_tapefd_unload): Likewise.
+         (plain_tapefd_status): Likewise.
+         (plain_tapefd_weof): Likewise.
+
+2000-12-07 Thomas Hepper <th@ant.han.de>
+
+       changer-src/scsi-changer-driver.c: Added Exabyte 230D Sense Handler
+       (patch from Gary Algier gaa@ulticom.com)
+       Fixed some compile warnings (-Wshadow)
+       changer-src/scsi-solaris.c: Changed the return Value from 
+       SCSI_ExecuteCommand to the value of Command.uscsi_status if
+       the return value of the ioctl is > 0
+
+2000-12-04 John R. Jackson  <jrj@purdue.edu>
+
+       server-src/amdump.sh.in: Temporary fix for $LOGNAME vs whoami problem.
+
+2000-12-04 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/security.c: Make the "./security" test code available
+         for normal operation by #define so it can be seen in, e.g., the
+         */amandad*debug file.
+
+2000-12-04 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/conffile.c (read_conffile_recursively): If the file name
+         for the includefile directive is not absolute, make it relative to
+         the configuration directory.
+
+2000-12-03 John R. Jackson  <jrj@purdue.edu>
+
+       * restore-src/amrestore.c: Fix header when compression is included.
+         Use "fast" option for -c and add new -C option to get "best".
+       * man/amrestore.8: Document the new option, the compression level,
+         and clean up some nroff issues.
+
+2000-11-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * Amanda 2.4.2 released
+       
+2000-11-22 John R. Jackson  <jrj@purdue.edu>
+
+       * contrib/dbbackup.ksh: Deal with adm being a symlink.
+       * contrib/dbbackup.tcl: Update for Tcl 8.3 and newer Oratcl versions.
+
+2000-11-22 John R. Jackson  <jrj@purdue.edu>
+
+       * Makefile.am: Forgot to add contrib/sst/README.Amanda to the list
+         of files to put in a distribution.
+
+2000-11-21 John R. Jackson  <jrj@purdue.edu>
+
+       * recover-src/extract_list.c (extract_files_child): Add support for
+         XFSRESTORE.
+
+2000-11-21 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcheck.c: Minor message wording changes.
+
+2000-11-21 John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: Forgot to check in this part of new amgetconf.8.in.
+
+2000-11-21 John R. Jackson  <jrj@purdue.edu>
+
+       * contrib/sst/README.Amanda: New file of Amanda specific sst notes.
+       * contrib/sst/sst.c: Attempt at letting gcc compile sst.
+
+2000-11-21 John R. Jackson  <jrj@purdue.edu>
+
+       * man/amgetconf.8.in: New man page.
+       * man/Makefile.am: Add support for amgetconf.8.in.
+       * man/amadmin.8.in: Update for 2.4.2 and do general cleanup.
+       * man/amanda.8.in: Ditto.
+       * man/amcheck.8.in: Ditto.
+       * man/amcheckdb.8.in: Ditto.
+       * man/amcleanup.8.in: Ditto.
+       * man/amdump.8.in: Ditto.
+       * man/amflush.8.in: Ditto.
+       * man/amlabel.8.in: Ditto.
+       * man/amrecover.8.in: Ditto.
+       * man/amreport.8.in: Ditto.
+       * man/amrestore.8: Ditto.
+       * man/amrmtape.8.in: Ditto.
+       * man/amstatus.8.in: Ditto.
+       * man/amtape.8: Ditto.
+       * man/amtoc.8.in: Ditto.
+       * man/amverify.8.in: Ditto.
+
+2000-11-21 John R. Jackson  <jrj@purdue.edu>
+
+       * contrib/sst/sst.c (sst_ioctl): Allow non-root users to use sst.
+
+2000-11-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amdump.sh.in: exit if amgetconf exit with status != 0.
+       * server-src/amcleanup.sh.in: ditto
+       * server-src/amstatus.pl.in: ditto
+
+2000-11-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (start_some_dumps): don't check free_kps if
+       curusage == 0.
+       * server-src/driver.c (free_kps): remove the kludge.
+
+2000-11-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.c: It's an error to have a negative chunksize.
+       * man/amanda.8.in: remove documentation of negative chunksize.
+       * example/amanda.conf.in: ditto
+       * example/amanda.conf.chg-scsi.in:ditto
+       * NEWS: negative chunksize is no longer supported.
+
+2000-11-03 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c (handle_taper_result): the holding disk entry
+       should not be removed just because taper could not write it out in
+       the "too many taper retries" case.  It should be left for amflush.
+
+2000-11-01 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: use common form for getting the first
+       line of a file/pipe.  Sed is more portable than head.
+
+2000-11-01 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/security.c (bsd_security_ok): Same fix for amwait_t !=
+       int as applied a while back to changer.c.  Compliments of John E.
+       Hein <jhein@timing.com>.
+
+2000-10-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/selfcheck.c (check_disk): Write an appropriate
+       message if the disk name start with '//' and the program is DUMP
+       or SAMBA is not compiled in.
+
+2000-10-29  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (continue_dumps): set estimate to more than
+       what is already use instead of setting no_hold=1 when a disk
+       don't fit on holding disk.
+
+2000-10-28  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: add '&' when calling &usage()
+       or &dump_size().
+
+2000-10-28  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       reported by The Hermit Hacker <scrappy@hub.org>
+
+       * changer-src/chg-chio.pl.in: remove unused $libexecdir.
+
+2000-10-28  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       reported by The Hermit Hacker <scrappy@hub.org>
+
+       * changer-src/chg-chio.pl.in: remove comma after LOG,
+       typo: r should be 0.
+
+2000-10-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/INDEXING: doc updated.
+
+2000-10-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/scsi-defs.h: prototype SCSI_Inquiry, PrintInquiry, 
+       DecodeSCSI, ChangerReplay, BarCode and MapBarCode.
+       * changer-src/scsi-linux.c: fix compiler warning.
+       * changer-src/scsi-changer-driver.c: fix compiler warning.
+
+2000-10-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * changer-src/chg-scsi.c: remove rcsid.
+       * changer-src/scsi-aix.c: remove rcsid, add amanda Copyright.
+       * changer-src/scsi-bsd.c: remove rcsid, add amanda Copyright.
+       * changer-src/scsi-changer-driver.c: remove rcsid, add amanda Copyright.
+       * changer-src/scsi-defs.h: add amanda Copyright.
+       * changer-src/scsi-hpux.c: remove rcsid.
+       * changer-src/scsi-hpux_new.c: remove rcsid, add amanda Copyright.
+       * changer-src/scsi-irix.c: remove rcsid, add amanda Copyright.
+       * changer-src/scsi-linux.c: remove rcsid, add amanda Copyright.
+       * changer-src/scsi-solaris.c: remove rcsid, add amanda Copyright.
+
+2000-10-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * AUTHORS: add Thomas Hepper.
+
+2000-10-14  Thomas Hepper <th@ant.han.de>
+
+       * changer-src/scsi-changer-driver.c: Added support for the TreeFrog
+       library (barcode support), fixed some signal 11 problems in the
+       output of chg-scsi -status
+       Removed unused variables
+       * changer-src/chg-scsi.c: same
+       * changer-src/scsi-defs.h: same
+
+2000-10-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amverify.sh.in: grep only the first line of the header.
+
+2000-10-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amverify.sh.in: verify with tar even if the
+       server and the client are not configured with the same path.
+
+2000-10-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * NEWS: A new `ctimeout' keyword in amanda.conf to replace
+       the CHECK_TIMEOUT constant in amcheck.c.
+
+2000-10-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amlabel.c: Don't set tape_ok to 0 if
+       tape_wrlabel is successful.
+
+2000-10-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/taper.c: amfree(strclosing).
+
+2000-10-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in: --with-samba-user is deprecated.
+       * docs/SAMBA: the username is now on the amandapass file.
+       * NEWS: the username is now on the amandapass file.
+       * client-src/findpass.c (findpass): accept "*" as diskname.
+       * client-src/selfcheck.c (check_disk): call to samba changed.
+       * client-src/sendsize.c (getsize_smbtar): ditto.
+       * client-src/sendbackup-gnutar.c (start_backup): ditto.
+       * recover-src/extract_list.c (extract_files_child): ditto.
+       
+2000-10-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c (write_tapeheader): set errno = ENOSPC
+       and return -1 if is not fully written.
+
+2000-10-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/taper.c: give better message when failing
+       to open a chunk.
+
+2000-10-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/diskfile.c (headqueue_disk): new function to
+       insert at the head of the queue.
+       * server-src/diskfile.h (headqueue_disk): prototype.
+       * server-src/driver.c (handle_taper_result,dump_to_tape):
+       insert with headqueue_disk() after a TRY-AGAIN.
+
+2000-10-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c (do_dump): wait for index compress
+       process to terminate before renaming the index file.
+
+2000-10-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * AUTHORS: fix my email address.
+
+2000-09-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c: Don't accept -m or -M option if MAILER
+       is not defined.
+       * server-src/reporter.c: Need a -f optionn if MAILER is not defined.
+
+2000-09-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       patch by <jeg@time.ucsc.edu>
+
+       * server-src/reporter.c (output_summary): check for tape_labels.
+
+2000-09-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amindexd.c: use strcasecmp to compare hostname.
+
+2000-09-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: fix plural misuse.
+
+2000-09-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amanda.8.in: add all pages in the SEE ALSO section.
+
+2000-09-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendbackup.c: set estr=NULL if the exclude
+       file doesn't exist.
+
+2000-09-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendbackup-gnutar.c: use exclude string estr 
+       instead of "estr".
+
+2000-09-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amreport.8.in: amreport does not rotate the log.
+       * man/amrestore.8: note on holdingdisk.
+       * restore-src/amrestore.c: update usage.
+       * server-src/amrmtape.sh.in: update usage.
+       * server-src/amverify.sh.in.usage: update usage.
+
+2000-09-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amoverview.pl.in: update usage information,
+       -config is no longer needed for ccompatibility with other program.
+       * man/amoverview.8.in: -config is no longer needed.
+
+2000-09-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (usage): show disklist command.
+
+2000-09-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * example/amanda.conf.in: chunk should not be larger than
+       MAX_FILE_SIZE - 1Mb.
+
+2000-09-24  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendsize.c (getsize_smbtar): remove unused debug_level 
+       variable.
+       * server-src/amlabel.c (main): init errstr to NULL, 
+       fix compiler warning.
+
+2000-09-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       patch by jason Thomas <jet@users.sourceforge.net>
+
+       * tape-src/tapetype.c: fix help message.
+
+2000-09-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       patch by Rudolf Cejka <cejkar@users.sourceforge.net>
+
+       * common-src/file.c (mkpdir): check p != NULL
+       * man/amstatus.8.in: typo
+
+2000-09-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       patch by Rudolf Cejka <cejkar@users.sourceforge.net>
+
+       * client-src/calcsize.c:sets correct program name,
+       prevent coredumps and some improrer command line error mesages
+
+2000-09-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/amanda.h: prototype clean_regex().
+       * common-src/match.c: new function clean_regex() that escape
+       all non-alphanumeric character.
+       * recover-src/extract_list.c (add_file, delete_file): use clean_regex().
+
+2000-09-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c: (start_server_check): check for the oldlog
+       directory.
+
+2000-09-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amtrmlog.c: better check of the oldlog directory.
+
+2000-09-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c: (start_server_check): don't check the tape
+        if tapedev is /dev/null.
+
+2000-09-22  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c (output_tapeinfo): test reversed for run_tapes.
+
+2000-08-01  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * client-src/sendbackup-gnutar.c (start_backup) <taropt>:
+       NULL-terminate it correctly.
+
+2000-07-18 John R. Jackson  <jrj@purdue.edu>
+
+       * changer-src/chg-chio.pl.in (do_time): fix chg-chio.pl timestamp
+       function to return a string instead of writing to stdout.
+
+2000-07-18 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/taper.c (file_reader_side): detach and destroy shared
+       memory areas on an error condition.  Found by Patrik Andersin
+       <cat@iki.fi>.
+
+2000-07-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendsize.c (getsize_dump,getsize_gnutar): set 
+       dumppid to the return value of pipespawn.
+
+2000-06-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/sendbackup.c (parse_options): set efile.
+
+2000-06-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/list_dir.c (add_dir_list_item): add at head of list.
+
+2000-06-12  Jeroen Ruigrok van der Werven  <asmodai@wxs.nl>
+
+       * server-src/amlabel.c (main): Do not amfree(config_name).
+
+2000-06-03 Thomas Hepper <th@ant.han.de>
+
+       * changer-src/scsi-defs.h: Add missing defines which are used by the
+       sense handler
+       * changer-src/scsi-solaris.c: Added patch to limit the recursion
+       in Scsi_ExecuteCommand.
+
+2000-06-02 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.c (pick_datestamp): convert ch to upper.
+
+2000-05-28  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * client-src/sendbackup-gnutar.c: Ignore `socket ignored' GNU tar
+       messages.
+
+2000-05-27 Ian Turner <vectro@pipeline.com>
+       * client-src/sendbackup.c (pipespawn): Moved to...
+       * common-src/pipespawn.c: ... new file.  Redirect all std
+       streams.  Support skipping arguments.
+       * common-src/pipespawn.h (pipespawn, skip_argument): Declare.
+       * common-src/Makefile.am (noinst_HEADERS): Added pipespawn.h.
+       (libamanda_la_SOURCES): Added pipespawn.c.
+       * client-src/sendbackup-dump.c, client-src/sendbackup-gnutar.c:
+       Adjust.
+
+2000-04-20 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: typo
+
+2000-04-20  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * recover-src/Makefile.am (LDADD): Removed libamtape.
+       Reported by Paul Yeatman <pyeatman@ucsd.edu>
+
+2000-04-16 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/taper.c: don't crash if the tapelist file
+       doesn't exist.
+
+2000-04-09  Frank Wojcik  <fwojcik@lucent.com>
+
+       * server-src/taper.c (detach_buffers): Fixed typo in error message.
+
+       * server-src/amrmtape.sh.in: Fix occurrence of `Infofile', that
+       should have been `InfoFile'.
+
+2000-04-09  Davide Marchignoli  <marchign@di.unipi.it>
+
+       * server-src/conffile.h (confparm_t): Added CTIMEOUT.
+       * server-src/conffile.c: Added ctimeout support.  Default to 30.
+       * example/amanda.conf.in: Likewise.
+       * man/amanda.8.in: Documented it.
+       * server-src/amcheck.c: Use ctimeout from configuration file instead
+       of CHECK_TIMEOUT.
+
+2000-04-09  Stan Brown  <stanb@awod.com>
+
+       * recover-src/amrecover.c (guess_disk): Omit DEV_PREFIX only if
+       it is actually a prefix of fsname.
+
+2000-04-09  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * server-src/amlabel.c (main): Check label *after* writing end mark.
+       
+2000-03-06 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amlabel.c: don't crash if the tapelist file
+       doesn't exist.
+
+2000-02-12 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: "0 dumpers busy" should be "0 dumper busy".
+
+2000-02-08 Thomas Hepper <th@ant.han.de>
+
+       * changer-src/scsi-linux.c (SCSI_ExecuteCommand) : Direction for the 
+       memcpy for the sense result was wrong, so every time the sense result
+       was 0x0.....
+
+       * changer-src/scsi-changer-driver.c (GenericElementStatus) : Added
+       flag to signal if it is either a tape drive or a library. 
+
+2000-01-31 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (force_one, force_bump_one): FORCE_FULL
+       and FORCE_BUMP are mutually exclusive.
+
+2000-01-30  Thomas Hepper <th@ant.han.de>
+
+       * changer-src/chg-scsi.c : Exit it tapedev in amanda.conf is not a 
+       number. 
+
+2000-01-21  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * server-src/amstatus.pl.in (prefix, exec_prefix): Refer to them
+       twice to avoid warnings of possible typo.
+
+       * amplot/amplot.awk: Ignore dumper's RQ-MORE-DISK.
+       Reported by David Wolfskill <dhw@whistle.com>
+       * amplot/amplot.awk: Handle taper's TRY-AGAIN like TAPE-ERROR.
+
+       * server-src/amstatus.pl.in: Compute and display TRY-AGAIN tape
+       errors.
+       Reported by David Wolfskill <dhw@whistle.com>
+
+       * man/amtoc.8.in: Document -w.
+
+2000-01-21  David Wolfskill  <dhw@whistle.com>
+
+       * server-src/amtoc.pl.in: Add `-w' to add new lines and form feeds.
+
+2000-01-21  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * man/amlabel.8.in: Tapes are no longer requested in reverse order
+       of amlabeling.
+       Reported by Brad Guillory <round@baileylink.net>
+
+       * server-src/amstatus.pl.in: New option --stats, to display
+       statistics about dumpers and taper.
+       * man/amstatus.8.in: Document it.
+
+2000-01-21  David Wolfskill  <dhw@whistle.com>
+
+       * server-src/amstatus.pl.in: Sort dumpers by number.
+
+2000-01-21  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * server-src/amstatus.pl.in: Remove bogus (?) line `$$host=1'.
+
+       * configure.in (MAILER): Warn or print an error if not found,
+       depending on whether server code is disabled or not.
+
+       * server-src/reporter.c (output_tapeinfo): Report used tapes
+       regardless of tape errors.
+
+       * config/acinclude.m4i (CF_WAIT): Simplify the test.  Declare wait()
+       in the global scope.
+
+2000-01-21  Garrett Wollman  <wollman@khavrinen.lcs.mit.edu>
+
+       * config/acinclude.m4i (CF_WAIT): Avoid warnings on systems
+       where `union wait' works but is deprecated.
+
+2000-01-21  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * recover-src/uscan.l (settape): Recognize it.
+       * recover-src/uparse.y: Parse it.
+       * recover-src/amrecover.h (set_tape): Declare it.
+       * recover-src/set_commands.c (set_tape): Implement it.
+       * recover-src/help.c (help_list): Document it.
+       * man/amrecover.8.in: Likewise.
+       * recover-src/extract_list.c (extract_files): Warn if tape device is
+       /dev/null.
+       * recover-src/amrecover.c (tape_device_name): Default to
+       server-determined default.
+
+2000-01-17  Thomas Hepper <th@ant.han.de>
+       * changer-src/scsi-changer-driver.c : Typo in CheckMove fixed .
+
+2000-01-17  Thomas Hepper <th@ant.han.de>
+
+       * configure.in: check for scsi/sg.h on linux, and if true
+       enable sg support
+
+       * changer-src/chg-scsi.c : New option -trace for debuging...
+       new option changer_ident to set the internal driver for the changer
+
+       * hanger-src/scsi-hpux_new.c: New function Tape_Status.
+       returns the status of the tape. (loaded/empty etc)
+       * changer-src/scsi-aix.c : Dummy function for Tape_Status
+       * changer-src/scsi-bsd.c : Dummy function for Tape_Status
+       * changer-src/scsi-irix.c : Dummy function for Tape_Status
+       * changer-src/scsi-solaris.c : Dummy function for Tape_Status
+       * changer-src/scsi-linux.c : Added better support for the sg driver.
+       * changer-src/scsi-changer-driver.c : New driver for ADIC SDX and DLT448
+       librarys
+       new function SDXMove for SDX library
+       new function CheckMove to check if a move is legal based on the infs
+       we get from the Mode Sense command
+       * changer-src/scsi-defs.h : Added types returned by Tape_Status
+
+2000-01-16  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * server-src/driver.c (handle_dumper_result): When failed, set
+       dp->inprogress to 0, not 1.
+
+2000-01-13  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * configure.in: Recognize alpha*-*-linux-* and sparc*-*-linux-*.
+
+       * tape-src/Makefile.am (../common-src/libamanda.$(LIB_EXTENSION)):
+       Allow for `make tapetype' before libamanda is built.
+
+       * server-src/amoverview.pl.in: Year doesn't take just 2 bytes.
+
+2000-01-06  David Wolfskill  <dhw@whistle.com>
+
+       * docs/TAPETYPES: Typo.
+
+2000-01-06  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * docs/TAPETYPES: Removed all tapetype entries.  Pointed to
+       example/amanda.conf, to the mailing list archives and to the on-line
+       tapetype list.  Explained the meaning of length, filemark and speed,
+       and how to build and use the tapetype utility.
+
+1999-12-12 John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: egrep was having trouble with quoting on some systems.
+       Broke it apart into multiple unquoted statements.  Also, changed the
+       script to run the steps on all dump tests and added "Label" as another
+       line to ignore.
+
+1999-12-12 John R. Jackson  <jrj@purdue.edu>
+
+       * tape-src/tapetype.c: tweak the algorithm to write files in both
+       passes and compute the tape mark size as the difference.  Never
+       report a negative tape mark size.  Various other minor cleanup.
+
+1999-11-29  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * client-src/sendbackup-gnutar.c (re_table): #if out the debugging
+       Samba messages unless SAMBA_VERSION < 2.
+
+1999-11-29  John E.P.Hynes  <john@hytronix.ne.mediaone.net>
+
+       * client-src/sendbackup-gnutar.c (re_table): Update for Samba 2.0.6.
+
+1999-11-10 John R. Jackson  <jrj@purdue.edu>
+
+       * recover-src/extract_list.c: report the tape server host in the
+         message to check the amidxtaped.debug file.   If extract_list_child
+         fails (such as when amidxtaped fails to read the tape), ask if
+         things should continue instead of aborting.
+
+1999-11-11  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * server-src/driverio.c (update_info_dumper): Discard information on
+       older same- or higher-level dumps.
+       * server-src/driver.c (dump_to_tape): Add comment that _dumper must
+       be called before _taper.
+
+       * docs/FAQ: Sometimes FQDNs are wrong for amandahosts.
+
+1999-11-10 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amindexd.c (build_disk_table): need to clear the old
+         disk history list before building a new one.
+
+1999-11-10 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/taper.c (label_tape): issue a warning when tapedev is
+         set to /dev/null.
+       * server-src/amcheck.c (start_server_check): make warning message
+         text the same for amcheck and taper when tapedev is /dev/null.
+
+1999-11-10 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcleanupdisk.c (main): try to remove empty holding disk
+         areas.
+       * server-src/holding.c (scan_holdingdisk): do not automatically remove
+         empty holding disk areas since this function is called by various
+         utilities and a dump might be in progress.
+
+1999-11-10  James FitzGibbon  <james@targetnet.com>
+
+       * server-src/infofile.c (put_info): d.size should have been
+       d.dsize.
+
+1999-11-09 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcheck.c (start_server_check): test tapedev for
+         "/dev/null" and issue warning that dumps will be thrown away.
+
+1999-11-02  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * common-src/amflock.c (struct flock): Do not assume the fields are
+       declared in any particular order.
+       Reported by Sean Kelly <kelly@plutotech.com>
+
+       * Makefile.am (EXTRA_DIST): Added contrib/set_prod_link.pl.
+       * docs/INSTALL: Likewise.
+
+1999-11-02  Ricardo Malta  <rmalta@bigfoot.com>
+       
+       * contrib/set_prod_link.pl: Create the links for a configuration
+       with --with-suffix.
+
+1999-11-02  Nicolas Mayencourt  <Nicolas.Mayencourt@cui.unige.ch>
+
+       * server-src/amtoc.pl.in: Correct a bug for total report.
+
+1999-11-01 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c (find_diskspace): make noisy holding space log
+         message conditional on HOLD_DEBUG.
+
+1999-11-01 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcleanupdisk.c (main): do not free the config name (it
+         was never alloc-d).
+
+1999-10-24  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * common-src/debug.c: Do not assume stderr is a compile-time
+       constant.  On glibc 2.2 (RedHat Linux 6.1), it is not.
+
+1999-10-11  Nicolas Mayencourt  <Nicolas.Mayencourt@cui.unige.ch>
+
+       * server-src/amtoc.pl.in: Add new options -i and -t.  Print original
+       size, instead of size on tape.
+
+1999-10-07 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/stream.c (stream_server): remove reference to portrange
+         variable.  Compliments of Randy Dees <rrd@amherst.com>.
+
+1999-10-03 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c (main): now that multiple results can come back
+         from taper and dumper without a handshake (e.g. NO-ROOM), we need to
+         process them all rather than just the first one.  Call the new
+         areads_dataready() function to peek and see if more data is ready.
+       * common-src/amanda.h: declare areads_dataready().
+       * common-src/file.c: define areads_dataready().  Fix some variable
+         types.  Fix a buffer expansion problem.  Add code to the test
+         program to force buffer expansion to be checked out.
+
+1999-10-03 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/file.c (areads_getbuf): fix a buffer allocation problem.
+
+1999-10-03 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/amflock.c (main): do not use aclose() in the configure
+         test case.  During configure we do not have areads_relbuf()
+         available and it makes configure think all the tests have failed.
+
+1999-10-03 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/amanda.h: protect the close macros and areads* from
+         out of range file descriptors.
+       * common-src/file.c: ditto.
+
+1999-10-02 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amindexd.c (build_disk_table): only "OK" results from
+         find_dump should be considered.
+
+1999-10-02 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/file.c (areads): when NO-ROOM became advisory and didn't
+         participate in a full handshake, it exposed a problem in areads()
+         where a static buffer was shared among all I/O.  Changed it to use
+         a separate buffer for each file descriptor.  Enhanced the test
+         program to check out the code.
+       * common-src/amanda.h: ditto
+       * restore-src/amidxtaped.c: minor areads/agets comment typo.
+       * server-src/amindexd.c: ditto
+
+1999-10-02 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c: delete #define of HOLD_DEBUG, it was increasing
+         the size of the amdump log file by a factor of 10 or more.  Anyone
+         who needs it can define it in CFLAGS or some other way.
+
+1999-09-29 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/dumper.c (do_dump): closed the dump messages file too
+         soon.
+
+1999-09-23  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * recover-src/extract_list.c (samba_extract_method): Default to
+       SAMBA_TAR, for similarity with other restore programs.
+       (extract_files_child): If restore with SMBCLIENT is enabled, explain
+       that Samba shares will be restored to the SMB share.
+
+1999-09-22 John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: wrong variable when processing LIBRARY_DIRS.  Fix
+         compliments of John M. Vogtle <jmvogtle@kodak.com>.
+
+1999-09-19 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: this script is important enough it should
+         not depend on having perl installed.  Clean up the AIX "mt status"
+         code.  Test for presense of other restore programs and check that
+         they are executable during processing.
+
+1999-09-19 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: put back an "mt status" wait loop I
+         erroneously removed, but protect it from AIX.
+
+1999-09-19 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/util.c: fix math in bind_portrange so ports requested
+         are between those the caller passed and make sure port 0 does not
+         accidentally get requested, which returns a non-privileged port.
+       * common-src/dgram.c: bind_portrange last port argument is inclusive.
+       * common-src/stream.c: ditto.
+       * recover-src/amrecover.c: ditto.
+       * recover-src/extract_list.c: ditto.
+
+1999-09-19 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c: do not send a FILE_WRITE to the taper when the
+         tape queue is empty during a TRYAGAIN (driver core dumped).
+
+1999-09-19 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/taper.c: fix protocol problems when out of tape.  Add
+         FAKE_TAPE_ERROR debugging code to simulate tape errors.  Fix problem
+         with command line argument processing.
+
+1999-09-18 John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: several compress/uncompress variables were not being
+         set properly.
+
+1999-09-18 John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/sendbackup.c: pclose returns a child exit status of the
+         pipe, not an errno, so do not try to strerror it.
+         Have the index child process exit with the pclose exit code.
+         Treat index failures as strange rather than fatal so the dump gets
+         fully processed.  It's more important to have the dump image than
+         to skip it just because indexing had a (possibly unrelated) problem.
+
+1999-09-15 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amtoc.pl.in: handle an image failing on one tape and
+         succeeding on the next.
+
+1999-09-15 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: generalize the "driver: state" parsing
+         so it can handle current and future information.
+
+1999-09-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server/driver.c (main): use the holding disk even if the
+       datestamped directory already exist.
+
+1999-09-14  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * configure.in: Get snapshot date from SNAPSHOT file, if it exists.
+       (VERSION): Add the date to it.
+       (SNAPSHOT_STAMP): AC_SUBST to the SNAPSHOT file, if it exists.
+       * Makefile.am (EXTRA_DIST): Added $(SNAPSHOT_STAMP).
+       (config.status): Depend on $(SNAPSHOT_STAMP).
+       (SNAPSHOT): Dummy rule to allow reconfigure if it's removed.
+
+       * config/Makefile.am: Remove all traces of acconfig.h.
+
+       * server-src/changer.c (changer_command): Fix for amwait_t != int.
+
+1999-09-13  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
+
+       * config/acinclude.m4i: Added comments for config/config.h.in to all
+       AC_DEFINEs.
+       * configure.in: Likewise.
+       * config/acconfig.h: Deleted.
+       * autogen: Updated.
+
+1999-09-13 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: protect against uname not returning
+         anything.
+
+1999-09-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c (start_server_check): use tapefile instead of
+       conf_tapelist to open the file (we no longer cd to the config file).
+
+1999-09-11 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/reporter.c: sigh -- it was right the first time.
+
+1999-09-11 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/reporter.c: lost a few too many lines with the amlogroll
+         changes to amreport.
+
+1999-09-11 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amindex.c: minor memory leak.
+
+1999-09-11 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcheck.c: remove duplicated code.
+
+1999-09-11 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/Makefile.am: use new amlogroll utility to rename the log
+         file to the datestamped name.
+       * server-src/amcheck.c: ditto.
+       * server-src/amcleanup.sh.in: ditto and call all utilities with the
+         config file name as an argument.
+       * server-src/amdump.sh.in: ditto and call all utilities with the
+         config file name as an argument.
+       * server-src/amflush.c: ditto.
+       * server-src/amlogroll.c: new utility.
+       * server-src/driverio.c: ditto and call all utilities with the
+         config file name as an argument.
+       * server-src/reporter.c: ditto.
+
+1999-09-10 John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/rundump.c: minor compiler warnings.
+       * common-src/security.c: minor compiler warnings.
+       * server-src/amindexd.c: minor compiler warnings.
+       * server-src/conffile.c: minor compiler warnings.
+
+1999-09-10 John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/sendsize.c: typo in previous patch and pick a better
+         variable name (ala other similar code).
+
+1999-09-10 John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/amandad.c: clean up error messages after a fork or exec*
+         failure.
+       * client-src/rundump.c: ditto.
+       * client-src/runtar.c: ditto.
+       * client-src/sendbackup.c: ditto.
+       * client-src/sendsize.c: ditto.
+       * restore-src/amidxtaped.c: ditto.
+       * server-src/amflush.c: ditto.
+
+1999-09-07 John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: Add --with-tmpdir to ./configure and use it for
+         all Amanda temporary files.  Default --with-dbgdir to --with-tmpdir.
+         Move libexec/getconf to sbin/amgetconf and add an optional
+         config parameter.  Add optional config parameter to several
+         other programs.
+         Add debugging to chg-chio.
+         Call new safe_cd() function in most programs to cd to --with-tmpdir
+         so if they drop core, it goes to a known spot.  Rename existing
+         core files so more than one failure may be tracked.  Remove most
+         chdir() and umask() calls (umask is set in safe_cd).
+       * amplot/amplot.sh.in: ditto.
+       * changer-src/chg-chio.pl.in: ditto.
+       * changer-src/chg-chs.sh.in: ditto.
+       * changer-src/chg-manual.sh.in: ditto.
+       * changer-src/chg-mtx.sh.in: ditto.
+       * changer-src/chg-multi.sh.in: ditto.
+       * changer-src/chg-rth.pl.in: ditto.
+       * changer-src/chg-scsi-chio.c: ditto.
+       * changer-src/chg-scsi.c: ditto.
+       * changer-src/chg-zd-mtx.sh.in: ditto.
+       * client-src/amandad.c: ditto.
+       * client-src/calcsize.c: ditto.
+       * client-src/killpgrp.c: ditto.
+       * client-src/rundump.c: ditto.
+       * client-src/runtar.c: ditto.
+       * client-src/selfcheck.c: ditto.
+       * client-src/sendbackup-gnutar.c: ditto.
+       * client-src/sendbackup.c: ditto.
+       * client-src/sendsize.c: ditto.
+       * common-src/alloc.c: ditto.
+       * common-src/amanda.h: ditto.
+       * common-src/amflock.c: ditto.
+       * common-src/debug.c: ditto.
+       * common-src/file.c: ditto.
+       * common-src/genversion.c: ditto.
+       * common-src/security.c: ditto.
+       * config/acconfig.h: ditto.
+       * dumper-src/gnutar.pl.in: ditto.
+       * restore-src/amidxtaped.c: ditto.
+       * server-src/Makefile.am: ditto.
+       * server-src/amadmin.c: ditto.
+       * server-src/amcheck.c: ditto.
+       * server-src/amcheckdb.sh.in: ditto.
+       * server-src/amcleanup.sh.in: ditto.
+       * server-src/amcleanupdisk.c: ditto.
+       * server-src/amdump.sh.in: ditto.
+       * server-src/amflush.c: ditto.
+       * server-src/amfreetapes.sh.in: ditto.
+       * server-src/amindex.c: ditto.
+       * server-src/amindex.h: ditto.
+       * server-src/amindexd.c: ditto.
+       * server-src/amlabel.c: ditto.
+       * server-src/amrmtape.sh.in: ditto.
+       * server-src/amstatus.pl.in: ditto.
+       * server-src/amtape.c: ditto.
+       * server-src/amtrmidx.c: ditto.
+       * server-src/amtrmlog.c: ditto.
+       * server-src/amverify.sh.in: ditto.
+       * server-src/changer.c: ditto.
+       * server-src/changer.h: ditto.
+       * server-src/conffile.h: ditto.
+       * server-src/diskfile.c: ditto.
+       * server-src/driver.c: ditto.
+       * server-src/driverio.c: ditto.
+       * server-src/dumper.c: ditto.
+       * server-src/find.c: ditto.
+       * server-src/getconf.c: ditto.
+       * server-src/holding.c: ditto.
+       * server-src/infofile.c: ditto.
+       * server-src/logfile.c: ditto.
+       * server-src/planner.c: ditto.
+       * server-src/reporter.c: ditto.
+       * server-src/tapefile.c: ditto.
+       * server-src/taper.c: ditto.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/Makefile.am: change OBJ_EXTENSION to OBJEXT in line
+         related to the "security" test tool.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * changer-src/chg-chio.pl.in: add -w to #! line to catch more errors.
+       * client-src/amandad.c: fix some compiler warnings.
+       * common-src/protocol.c: fix some compiler warnings.
+       * recover-src/display_commands.c: fix some compiler warnings.
+       * recover-src/extract_list.c: fix some compiler warnings.
+       * restore-src/amrestore.c: fix some compiler warnings.
+       * server-src/conffile.c: fix some compiler warnings.
+       * server-src/diskfile.c: fix some compiler warnings.
+       * server-src/holding.c: fix some compiler warnings.
+       * server-src/planner.c: fix some compiler warnings.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * recover-src/extract_list.c: add VRESTORE and VXRESTORE support.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/stream.c: make sure errno is returned properly from
+         stream_client() and stream_server().
+       * client-src/sendbackup.c: report errors from stream_server() and
+         abort.
+       * server-src/taper.c: ditto.
+       * recover-src/extract_list.c: make sure errno is preserved.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/amandad.c: clean up a couple of debugging messages.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * recover-src/amrecover.c: add missing ntohs calls.  Reported by
+         Kent Kalnasy <kkalnasy@ms.washington.edu>
+       * recover-src/extract_list.c: ditto.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: make sure the dump and restore programs are defined
+         in pairs, do not allow just the dump program without restore.
+       * client-src/sendbackup-dump.c: assume restore program is present
+         if dump program is.
+       * common-src/genversion.c: assume restore program is present if
+         dump program is.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/genversion.c: CLIENT_LOGIN has to be defined so there
+         is no point testing for it.
+       * server-src/conffile.c: ditto.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: add SMBCLIENT, VRESTORE, VXRESTORE
+         and XFSRESTORE support.
+
+1999-09-05 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/conffile.c: add several common abbreviations to config
+         file processing.
+
+1999-09-01 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amtoc.pl.in: allow multiple -s entries.
+
+1999-09-01 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/reporter.c: handle/report a common columnspec syntax
+         error instead of dumping core.
+
+1999-09-01 John R. Jackson  <jrj@purdue.edu>
+
+       * man/amanda.8.in: typo in columnspec description.
+
+1999-09-01 John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/dgram.h: expressions in #define should be protected by
+         parenthesis.
+
+1999-08-25  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * changer-src/chg-chs.sh.in (changerdev): Pass it as -f flag to CHS.
+       * docs/TAPE.CHANGERS: Document it.
+       Reported by Mike Horansky <moho@stanford.EDU>
+
+       * server-src/conffile.c (read_dumptype): Renamed from get_dumptype.
+       Extended to support reading a named dumptype from a specified FILE.
+       (get_dumptype): Use read_dumptype.
+       (main): Read disklist, so that custom dumptypes are shown.
+       * server-src/conffile.h (read_dumptype): Declare.
+       * server-src/diskfile.c (read_diskline): Use read_dumptype if
+       dumptype starts with `{'.
+       * man/amanda.8.in (disklist): Document it.
+       * NEWS: Likewise.
+       * example/disklist: Exemplify it.
+
+1999-08-23 John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/reporter.c (copy_template_file): make sure all data is
+         written to label template pipeline.
+
+1999-08-21  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+       Patch by Peter Conrad <conrad@opus5.de>
+
+       * docs/INTERNALS: documented splitting of dumps across multiple
+         holding disks.
+       * server-src/conffile.c: make sure that disksize and chunksize
+         are multiple of TAPE_BLOCK_SIZE.
+       * server-src/diskfile.c (find_disk): new function to see if a
+         given disk is contained in a list structure.
+       * server-src/diskfile.h (find_disk): prototype.
+       * server-src/driverio.h (RQ_MORE_DISK): Added message.
+       * server-src/driverio.h (free_assignedhd): prototype.
+       * server-src/driverio.h (assignedhd_t): new data structure.
+       * server-src/driverio.c (cmdstr): added comamnd RQ-MORE-DISK.
+       * server-src/driverio.c (dumper_cmd): Modified format of CONTINUE
+       * server-src/driverio.c (free_assignedhd): new function to free an
+         array of assignedhd_t.
+       * server-src/driver.c (roomq): new queue to replace stoppedq.
+       * server-src/driver.c (find_diskspace, assign_holdingdisk, 
+         adjust_diskspace, delete_diskspace): rewrite.
+       * server-src/driver.c (continue_dumps): new function to determine
+         which dump should be continued.
+       * server-src/driver.c (handle_taper_result): call continue_dumps
+         to restart a roomq dump.
+       * server-src/driver.c (handle_dumper_result): some rewrite, 
+         modified semantics of NO_ROOM, new message RQ-MORE-DISK.
+       * server-src/dumper.c (main): Modified parsing of FILE_DUMP, 
+         handling of use.
+       * server-src/dumper.c (write_dataptr): NO-ROOM is informational only,
+         trucate the file to a multiple of TAPE_BLOCK_BYTES.
+       * server-src/dumper.c (update_dataptr): rewrite to emit RQ-MORE-DISK
+         command.
+
+1999-08-16  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * common-src/Makefile.am: Replace .o with OBJEXT.  List sources
+       explicitly, instead of LDADDing the corresponding objects.
+       (OBJ_EXTENSION): Wipe out, use OBJEXT.
+
+       * configure.in: Call AC_OBJEXT.
+       (LTLIBOBJS, LTALLOCA): Define, according to ac_objext.
+       * common-src/Makefile.am (libamanda_la_LIBADD): Use them.
+       (libamanda_a_LIBADD): Use LIBOBJS and ALLOCA.
+
+       * common-src/Makefile.am (genversion.o): Revert last change, it was
+       just a bug in automake's --disable-dependency-tracking.
+
+1999-08-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * README (platforms): Added OpenBSD.
+       Reported by Ian Darwin <ian@sq.com>
+       (platforms): Added SunOS 5.7.
+
+1999-08-15  Derek Ney <derek@hipgraphics.com>, Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c (SAMBA_DEBUG_LEVEL): New macro, "0" for
+       Samba >= 2, "3" for older ones.
+       (getsize_smbtar): Use `du' if SAMBA_VERSION >= 2, and the
+       appropriate SAMBA_DEBUG_LEVEL.
+
+1999-08-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * common-src/Makefile.am (genversion.o): Depend on genversion.c
+       too.  It seems that IRIX's make doesn't work without it.
+       Reported by Brian Cuttler <brian@wadsworth.org>
+
+1999-08-15  Jon LaBadie  <jon@jgcomp.com>
+
+       * tape-src/tapetype.c: Speed it up by using larger sections in the
+       second pass.
+
+1999-08-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/amanda.8.in (skip-full, incronly): Document existing bugs.
+
+       * server-src/conffile.c (init_defaults): Default disksize to 0.
+       * man/amanda.8.in (holdingdisk use): Document it.
+       Reported by Grant Beattie <Grant.Beattie@fulcrum.com.au>
+
+       * server-src/planner.c (setup_estimate): Typo.
+       (next_level0): Typo.
+
+       * config/ltconfig, config/ltmain.sh: Update from libtool 1.3.3.
+
+       * example/amanda.conf.in: Clarify holdingdisk::use 0.
+
+       * config/missing: Update from automake 1.4a.
+
+1999-07-04 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amanda.8.in: typo.
+
+1999-06-29  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/amrestore.8: Document holding-file usage.
+
+1999-06-25  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * Makefile.am (pkgdata_DATA): Install COPYRIGHTs.
+       (EXTRA_DIST): Remove docs/*.
+       * docs/Makefile.am: New file.
+       (pkgdata_DATA): Install all docs.
+       * configure.in: Output docs/Makefile.
+       Suggested by Paul L. Lussier <plussier@baynetworks.com>
+
+       * docs/FAQ (selfcheck time-out): NIS services, inetd rebooting,
+       keyboard time-out, lsof.
+
+       * server-src/amverify.sh.in (HEADER): Use `sed 1q'  instead of the
+       not-that-portable `head -1'.
+       Reported by Andrew Lare <lare@eos913c.gsfc.nasa.gov>
+
+1999-06-20  Thomas Hepper <th@ant.han.de>
+
+       * changer-src/chg-scsi.c: 2 new config keywords, changerident/tapeident
+       
+       * changer-src/scsi-changer-driver.c: deleted the linux driver at the
+       beginning, (wrong window on cut and paste .......)
+
+       * changer-src/scsi-defs.h: new element in Changer_IO which describes
+       the type of device which is handled by this entry (tape/robot)
+
+       * changer-src/scsi-changer-driver.c: New parameter to OpenDevice
+       to override the selection of the driver for this device. (See
+       also docs/TAPE.CHANGERS)
+
+1999-06-19  Alexander Zangerl  <az@Austria.EU.net>
+
+       * client-src/sendbackup-dump.c (re_table): Match Solaris vxdump
+       output.
+
+1999-06-18  Thomas Hepper <th@ant.han.de>
+
+       * server-src/changer.c: (changer_find) check if serachlabel is NULL
+       if yes don't print it to the debug file
+
+       * changer-src/scsi-solaris.c: (SCSI_ExecuteCommand) Add missing
+       parameter to DecodeExtSense.
+
+       * changer-src/scsi-aix.c: (SCSI_ExecuteCommand) Add missing
+       parameter to DecodeExtSense.
+
+       * changer-src/scsi-hpux.c: Added static char rcsid[] = ...
+       * changer-src-/chg-scsi.c: dito
+       * changer-src/scsi-changer-driver.c: dito
+
+1999-06-17  Thomas Hepper <th@ant.han.de>
+
+       * configure.in: Add new example files amanda.conf.chg-scsi, 
+       chg-scsi-linux.conf, chg-scsi-solaris.conf, chg-scsi-hpux.conf
+
+       * changer-src/chg-scsi-chio.c: Add parameter to find_empty
+
+       * changer-src/chg-scsi.c: Changed the way files are opened, added
+       FILE *debug_file because now it is possible to send some output to
+       stdout. (scsi-changer-driver.c).
+       (ask_clean) return 0  if result from get_clean_state is < 0
+       if get_current_slot returns < 0 try to find the used slot by asking
+       the robot. (happens if no slot file is available, or slot file is empty)
+       
+       * changer-src/scsi-changer-driver.c: New tape/robot types.
+       (find_empty) new parameter to specify range where to search.
+       More checks for NULL pointer ....
+       (DumpDev) new function to print the info for the device struct.
+       (ChangerStatus) some more output ....
+       
+       * changer-src/scsi-linux.c: Complete rewrite of SCSI_OpenDevice.
+
+       * common-src/debug.c: (debug_fp) new function to return the FILE *
+       to the debug file.
+
+       * contrib/sst/sst.c: Removed the inquiry call, this is handled by
+       chg-scsi. The old version will hang if for example no tape is loaded.
+       
+       * contrib/sst/Makefile: New Makefile, the old one does not work if not
+       the complete SUNdrv kit is installed.
+
+
+1999-06-15  Adam Hammer  <hammer@math.purdue.edu>
+
+       * server-src/amverify.sh.in: Wait until device becomes ready after
+       rewinding.
+
+1999-06-15  Björn Brezger <Bjoern.Brezger@uni-konstanz.de>, Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/calcsize.c (ROUND): Rewrite, it was broken.
+       Reported by Erik Lindahl <erik@theophys.kth.se>
+
+1999-06-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/conffile.h: Changed all `long's to `int's, as they
+       broke get_number et al on 64bit platforms.
+       Reported by Erik Lindahl <erik@theophys.kth.se>
+
+       * configure.in (bcopy, bzero): Oops, ICE_CHECK_DECL already checks
+       for availability.
+
+       * configure.in (bcopy, bzero): Check whether they're available.
+       * common-src/amanda.h (bcopy, bzero): If not, use memmove and
+       memset.
+       Reported by Grant Beattie <Grant.Beattie@fulcrum.com.au>
+
+       * server-src/amcheck.c (start_server_check): If info file does not
+       exist, explain that it is supposed to be created on the next run.
+
+1999-06-08  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/tapefile.c (lookup_last_reusable_tape): Fix order of
+       arguments in match() invocation.
+       From Anthony Worrall <Anthony.Worrall@reading.ac.uk>
+
+1999-06-08  Mike Grupenhoff <kashmir@munge.com>
+
+       * restore-src/amrestore.c: second arg to restore() is a char *, not
+       a string_t.  Adjust prototype accordingly.
+
+1999-06-07  Mike Grupenhoff <kashmir@munge.com>
+
+       * common-src/util.c (bind_portrange): function that attempts
+       to bind a network connection to a port in a given range.
+       * common-src/util.h: prototype bind_portrange().
+       * common-src/dgram.c (bind_reserved): remove, superceeded by
+       bind_portrange().
+       (dgram_bind): use bind_portrange() instead of bind_reserved(), and
+       try user specified ports first, then reserved ports, then regular
+       ports.
+       * common-src/dgram.h: remove prototype for bind_reserved().
+       * common-src/stream.c (stream_server, stream_client): use
+       bind_portrange() instead of bind_reserved(), and try user
+       specified ports first, then reserved ports, then regular
+       ports.
+       * recover-src/amrecover.c (main): use bind_portrange() instead
+       of bind_reserved(), and verify that the port it gives us is
+       a reserved one.
+       * recover-src/extract_list.c (extract_files_setup): use
+       bind_portrange() instead of bind_reserved(), and verify that
+       the port it gives us is a reserved one.
+
+1999-06-07  Mark F. Vlems  <mvlems@vbox.xs4all.nl>
+
+       * server-src/amindexd.c (reply, lreply, fast_lreply): Return code 0
+       of printf does not imply an error on some systems (Openstep) even if
+       the number of written characters is more than 0.  The weakened error 
+       check has no implication for the correct implementations of printf.
+
+1999-06-03  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/driver.c (dump_to_tape): Tell hard from soft
+       (retryable) failures in both dumper and taper results, and behave
+       accordingly.
+
+       * docs/SYSTEM.NOTES: On Trusted Solaris, the format of inetd.conf is 
+       slightly different.
+       Reported by Julian Stevens <julian.stevens@baedsl.co.uk>
+
+1999-06-01  John Williams  <williams@morinda.com>
+
+       * changer-src/scsi-hpux.c (eject_tape): Enable it, it works.
+
+1999-06-01  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/INSTALL: Point to the patches page.  Update version numbers.
+
+       * example/config.site: Document UDPPORTRANGE.
+
+1999-06-01  Jens Persson  <jens.persson@btj.se>
+
+       * configure.in (UDPPORTRANGE): Set from --with-udpportrange.
+       * config/acconfig.h: Add UDPPORTRANGE.
+       * common-src/dgram.c: Implement it.
+
+1999-05-27  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * config/ltconfig, config/ltmain.sh, config/libtool.m4i: Updated
+       to libtool 1.3.2 plus a few patches.
+       * config/config.guess, config/config.sub: Ditto.
+
+1999-05-25  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ (tar-patch): Mention sparse file problem.
+
+       * recover-src/uscan.l: #undef `ECHO' after #include amanda.h; some
+       system header files may define it.
+       Reported by Dan Lipofsky <danlip@cyc.com>
+
+       * */Makefile.am: Do not define ACLOCAL_M4, COMPILE or
+       AMANDA_CFLAGS.
+       * Makefile.am: Create acinclude.m4 in the top-level directory.
+       * config/Makefile.am: Create link to acconfig.h in the top-level
+       directory.
+       * configure.in: Add AMANDA_CFLAGS to CFLAGS.
+       * common-src/Makefile.am: Create genversion.h with #defines, to
+       avoid genversion-specific CPPFLAGS.
+       * common-src/genversion.c: #include genversion.h
+       * common-src/version.h: VERSION_COMMENT must be const, as in
+       version.c.
+
+1999-05-24  Mike Grupenhoff <kashmir@munge.com>
+
+       * server-src/amcheck.c (main): if we reap a bogus pid, print
+       out the error message we generate, instead of whatever junk
+       happens to be in the buffer.
+
+1999-05-23  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/amindex.h: Keep P macro expression in a single line.
+       Reported by Patrick Harrold <patrickh@nasco-inc.com>
+
+       * common-src/Makefile.am (statfs_LDADD): Added alloc.obj.
+
+       * common-src/statfs.c (STATFS_SCALE, sys/statvfs.h): If f_frsize is
+       zero, use f_bsize.  It now works with GNU libc 2.1.
+       Reported by Heikki Vatiainen <hessu@cs.tut.fi>
+
+1999-05-22 Alex Pilosov <alex@pilosoft.com>
+
+       * server-src/amindexd.c (is_dump_host_valid): sanitize_name(host)
+       before doing a stat.
+       * server-src/tapefile.c (lookup_nb_tape): init pos to 0.
+
+1999-05-19 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: take the orig size from the SUCCESS line.
+       use value from the infofile only the datestamp are equal.
+       Write all available value.
+
+1999-05-15 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (pick_inclevel): check for base_level+1 if
+       we don't have estimate for base_level. Needed for FORCE_BUMP.
+       * server-src/planner.c (promote_highest_priority_incremental):
+       Don't promote if we don't have level 0 estimate. No more need
+       to check for skip_full, DS_NOFULL, DS_INCRONLY or FORCE_BUMP.
+
+1999-05-15 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amflush.c: ignore SIGPIPE
+       * server-src/driver.c: ignore SIGPIPE
+       * server-src/driverio.c (taper_cmd, dumper_cmd): return 0 on error, 
+       1 on success.
+       * server-src/driverio.h (taper_cmd, dumper_cmd): prototype.
+
+1999-05-14  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/TAPE.CHANGERS (chg-rth): URL for chs is no longer valid.
+
+1999-05-10  Mike Grupenhoff <kashmir@munge.com>
+
+       * client-src/sendsize.c (getsize_dump): print out the strerror
+       if we can't exec killpgrp.
+
+1999-05-07 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * example/amanda.conf.in: typo
+
+1999-05-05  Mike Grupenhoff <kashmir@munge.com>
+
+       * server-src/amverify.sh.in (pecho): new function.  Like echo
+       but doesn't append newline, and supports \r, etc.  Implemented
+       using perl.
+       * server-src/amverify.sh.in: use pecho where we used to use echo -n,
+       etc.  It's nearly impossible to figure out which echo needs what
+       flags and also know if it supports \r.  So we just punt and use
+       perl.
+
+1999-04-29 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (when_overwrite): return a big number (1024)
+       if the tape is not reusable.
+
+1999-04-29  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * config/ltconfig, config/ltmain.sh, config/libtool.m4i: Updated
+       from libtool 1.3.
+
+1999-04-25  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * common-src/versuff.c.in: Adjust constness to match version.h.
+
+       * docs/SYSTEM.NOTES: Recommend GNU tar for Linux.
+
+1999-04-25 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amdump.sh.in: execute amtrmlog.
+
+1999-04-22 John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: add --with-broken-fsf to use a read() loop instead
+       of the fsf ioctl on some broken systems.
+       * config/acconfig.h: ditto
+       * tape-src/tapeio.c (tapefd_fsf): ditto
+
+1999-04-22  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SYSTEM.NOTES: Typo
+       * docs/SAMBA: Update on samba-largefs patch.
+       * docs/FAQ: New FAQ about promotion of full dumps.
+
+1999-04-20  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * tape-src/tapeio.c (tape_open): Retry after EBUSY and EINTR too.
+       Comment out test that would set filename to /dev/null.
+
+1999-04-18  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/WISHLIST: Global reformat.  Removed fixed issues.  Added
+       auto-flush mode.
+
+1999-04-17 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/server_util.c: new file for utility function. 
+       New function construct_datestamp.
+       * server-src/server_util.h: ditto
+       * server-src/makefile.am: link server_util.c with libamserver.
+       * amcleanupdisk.c (construct_datestamp): remove function.
+       * server-src/driver.c: ditto
+       * server-src/dumper.c: ditto
+       * server-src/amflush.c: ditto
+       * server-src/planner.c: ditto
+
+1999-04-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/UPGRADE: Update URL for archived message.
+
+1999-04-07 John R. Jackson  <jrj@purdue.edu>
+
+       * tape-src/tapeio.c: allow tapedev to be /dev/null.
+       * server-src/taper.c: allow tapedev to be /dev/null.
+       * man/amanda.8.in: allow tapedev to be /dev/null.
+
+1999-04-06 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c (TextRule): Fix to write the full string.
+
+1999-04-06  David Mankins <dm@k12-nis-2.bbn.com>
+
+       * common-src/security.c (bsd_security_ok): if an .amandahosts
+       file is missing or unreadable, log this fact to the debug file
+       instead of claiming that a user doesn't have permission.
+
+1999-04-01 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c: -t should read the tapelist to validate
+       the label.
+
+1999-03-30  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * patches/samba-largefs.patch: updated to patch that ended up
+       installed in the Samba CVS tree
+
+       * patches/tar-1.12.patch: patch the configure script so that it
+       requires autoconf and autoheader to be run; improve the
+       printf_long_long test so that it doesn't get false positives because 
+       of endianness
+
+       * changer-src/scsi-chio.c: since we do not support FreeBSD 3's
+       camlib.h interface, #ifdef out all the code
+       Reported by Francis Lam <Francis.Lam@Leitch.com>
+
+       * configure.in (VXSYSLOCPATH): apparently a complex path expression
+       gets AC_PATH_PROGS confused; set the path beforehand
+       Reported by Francis Lam <Francis.Lam@Leitch.com>
+
+1999-03-28 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: compiler warning.
+
+1999-03-28 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amtrmlog.c: new program to move unused log 
+       to logdir/oldlog.
+       * server-src/Makefile.am: install amtrmlog.
+       * server-src/find.h: declare find_log().
+       * server-src/find.c(find_log): new function to return an array of
+       all the logfile name that are still needed.
+       * server-src/find.c(search_logfile): special case if output_find==NULL,
+       return 1 if it the logfile fir the label.
+
+1999-03-25  Neil Crellin  <neil@wallaby.cc>
+
+       * docs/TAPE.CHANGERS (chg-chs): URL for chs
+
+1999-03-25  Alexandre Oliva  <oliva@dcc.unicamp.br>, Tom Schutter  <tom@platte.com>, Cloyce D. Spradling  <cloyce@headgear.org>
+
+       * patches/samba-largefs.patch: updated for Samba 2.0.*
+
+1999-03-25  Charles Owens  <owensc@enc.edu>
+
+       * changer-src/chg-chio.pl.in (changeTape): do not print status to
+       both stdout and stderr; this causes failures on FreeBSD
+
+1999-03-21  Elmar Bartel  <bartel@Informatik.TU-Muenchen.DE>
+
+       * conffile.h, conffile.c: new columnspec option
+       * reporter.c: use it
+       * man/amanda.8.in: description and example
+       * example/amanda.conf.in: ditto
+
+1999-03-20  Dahn Nilsson <dahn.nilsson@maxlab.lu.se>
+
+       * configure.in: SAMBA_VERSION is not set correctly.
+
+1999-03-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendbackup-dump.c (re_table): generalize a bit some of
+       the regular expressions, so as to make us more adaptable to future
+       minor changes and bugfixes the the output format of some dumps
+
+1999-03-15 Thomas Hepper <th@ant.han.de>
+       * changer-src/chg-scsi.c: If the open of the TapeDevice fails
+       the programm is not terminated.
+       * changer-src/scsi-aix.c: The wrong ident string was checked
+       for 0 termination.
+       * changer-src/scsi-bsd.c: see scsi-aix.c
+       * changer-src/scsi-linux.c: see scsi-aix.c
+       * changer-src/scsi-solaris.c: see scsi-aix.c
+       * changer-src/scsi-changer-driver.c: Added some more debug prints.
+       Wrong fd passwd to LogSense.
+       * docs/TAPE.CHANGERS: added note about linux and aha1542
+
+1999-03-15   Michael Povel  <mcp@ladyada.han.de>
+       * server-src/amlabel.c: Wrong parameter to changer_label
+       * server-src/amtape.c: New function update_one_slot,
+       update_labeldb
+       * server-src/changer.c: Changed slotsp from int to char, some
+       debug prints.
+       * server-src/changer.h: Changed prototype for changer_label
+
+1999-03-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * config/ltconfig, config/ltmain.sh: updated from libtool 1.2f
+       * config/libtool.m4i, config/config.guess, config/config.sub: ditto
+       * configure.in: dropped AC_PROG_RANLIB, as suggested by libtoolize
+
+1999-03-14  Mathias Herberts  <Mathias.Herberts@ago.fr>
+
+       * man/amrecover.8.in: document mode and setmode
+
+1999-03-14  Jon Stevens  <jon@clearink.com>
+
+       * common-src/security.c (bsd_security_ok): increase the verbosity of 
+       failed authentication messages
+
+1999-03-14  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (powerpc-*-linux-*): supported platform
+       * README: ditto
+       Reported by Jon Stevens <jon@clearink.com>
+
+1999-03-07 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c (startup_dump): rename dumpname to progname. 
+       the function will use the parameter progname instead of the
+       global variable.
+
+1999-03-06  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (openbsd): according to Ralf Gebhart
+       <rgebhart@cybernet-ag.net>, sparc-unknown-openbsd2.3 is supported;
+       I assume other openbsd platforms work too.
+
+1999-03-05 Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in: set SAMBA_VERSION
+       * client-src/sendbackup-gnutar.c (start_backup): use -q flag
+       if SAMBA_VERSION >= 2
+
+1999-03-05 Mathias Herberts <Mathias.Herberts@ago.fr>
+
+       * recover-src/amrecover.h (set_mode, show_mode) declare new functions.
+       * recover-src/amrecover.h (SAMBA_SMBCLIENT, SAMBA_TAR) define new
+       constant.
+       * recover-src/extract_list.c: declare variable samba_extract_method.
+       * recover-src/extract_list.c (extract_files_child): set dumptype 
+       according to samba_extract_method.
+       * recover-src/help.c (help_list): print help for new command mode
+       and showmode.
+       * recover-src/set_commands.c (set_mode, show_mode): new functions.
+       * recover-src/uscan.l:
+       * recover-src/uparse.y:
+
+1999-03-04  Thomas Hepper <th@ant.han.de>
+       * configure.in Check if samba tar accept the q option
+       * changer-src/chg-scsi.c New command -status. Display slot status.
+       add debug prints to parse_args. Missing {} in case COM_SLOT 
+       add put_current_slot if reset was successfull
+       * changer-src/aix.c Init struct pwork with 0's.
+       Fixed error in copy of the product indent form the inquiry
+       * changer-src/scsi-bsd.c see aix.c
+       * changer-src/scsi-hpux_new.c see aix.c
+       * changer-src/scsi-irix.c see aix.c
+       * changer-src/scsi-linux.c see aix.c
+       * changer-src/scsi-solaris.c see aix.c
+       * changer-src/scsi-changer-driver.c New function TerminatString,
+       places 0 from the end of a string until first char/num
+       Fixed wrong parameter for GenericRewind in LogSense
+       In GenericElementStatus terminate VOL Tag String with 0
+       New function CHangerStatus. dumps changer info on stdout.
+       * changer-src/scsi-defs.h VolTag[TAG_SIZE+1] to have place for
+       terminating 0
+       * client-src/sendbackup-gnutar.c Add option q to tar call if
+       samba tar understand q option
+       * config/acconfig.h New define if samba tar accepts q option
+       * docs/TAPE.CHANGERS Add note on how to init the labelfile      
+
+
+1999-03-03  Ralf Fassel <ralf@akutech.de>
+
+       * common-src/conffile.h: bit field of length 1 should be unsigned int,
+       not int.
+
+1999-03-01  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h: new parameter level to update_info_taper().
+       * server-src/driverio.c (update_info_taper): use parameter instead
+       of sched(dp)->level.
+       * server-src/driver.c: call update_info_taper with level parameter.
+       * server-src/amflush.c: call update_info_taper with level parameter.
+       no longer need to create a sched_t struct.
+
+1999-03-01  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h: remove declaration of inparallel, cmdstr()
+       and childstr(), declare init_driverio(), add inparallel parameter
+       to startup_dump_processes().
+       * server-src/driverio.c (init_driverio): new function to initialize
+       dmptable and taper.
+       * server-src/driverio.c (childstr): scan for all dumpers (MAX_DUMPERS)
+       instead of only inparallel
+       * server-src/driverio.c (startup_dump_processes): new parameter
+       inparallel is used instead of global variable.
+       * server-src/driver.c (main): call init_driverio.
+       * server-src/driver.c (main): call startup_dump_processes with
+       inparallel parameter.
+       * server-src/amflush.c (main): call init_driverio.
+
+1999-03-01  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amrmtape.sh.in: work with "last_level" and 
+       "consecutive_runs" in the ouput of "amadmin export".
+
+1999-02-28  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/WISHLIST: protocol between the driver and dumpers.
+
+1999-02-28  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amtoc.pl.in: output the datestamp of each dump, because
+       amflush can flush the same disk multiple date.
+
+1999-02-27  Thomas Hepper <th@ant.han.de>
+       * server-src/amlabel.c fixed call to changer_label
+
+1999-02-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.h: declare struct holding_t.  Remove
+       declaration of insert_dirname, scan_holdingdisk.  Declare
+       new function free_holding_list.  pick_datestamp and 
+       pick_all_datestamp now return (holding_t *).
+       * server-src/holding.c (insert_dirname): new parameter holding_list
+       where we add the name. Can add more than MAX_DIRS name.
+       * server-src/holding.c (free_holding_list): new function to free
+       a holding list.
+       * server-src/holding.c (scan_holdingdisk): new parameter holding_list.
+       * server-src/holding.c (pick_all_datestamp, pick_datestamp): return
+       a list instead of a (char **).
+       * server-src/find.c (search_holding_disk): use the list return by
+       pick_all_datestamp.
+       * server-src/amflush.c: use the list return by pick_datestamp.
+       * server-src/amcleanupdisk.c (check_disks): use the list return by
+        pick_all_datestamp.
+
+1999-02-26 Thomas Hepper <th@ant.han.de>
+
+       * changer-src/chg-scsi.c Added global structs for the openend
+       devices. Added new options label and search for the barcode
+       support. New function MapBarCode, map barcode from reader
+       to amanda tape labels.
+       *changer-src/scsi-aix.c Error in copying SCSI ident fixed. 
+       A space mut not be the end of the string...
+       * changer-src/scsi-bsd.c same as scsi-aix.c 
+       * changer-src/scsi-irix.c same as scsi-aix.c 
+       * changer-src/scsi-solaris.c same as scsi-aix.c 
+       * changer-src/scsi-hpux_new.c same as scsi-aix.c 
+       * changer-src/scsi-linux.c same as scsi-aix.c , fixed
+       error in check if we open an sg device.
+       * changer-src/scsi-changer-driver.c Removed LookupFunction
+       and LookupDevice functions .
+       * docs/TAPE.CHANGERS update info about chg-scsi
+
+1999-02-26  Michael Povel  <mcp@ladyada.han.de>
+
+       * server-src/amcheck.c Added debug output for barcode
+       support
+       * server-src/amlabel.c Added debug output, inform chg-scsi
+       on new label
+       * server-src/amtape.c Added debug output, inform chg-scsi
+       on new label
+       * server-src/changer.c Added debug output, filled function
+       changer-label with live, label search should work now
+
+1999-02-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.c (addfd): bug fixe.
+
+1999-02-22  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendbackup-gnutar.c: new regexp for SAMBA
+       Reported by Grzegorz Mucha <grzegorz.mucha@solidex.com.pl>
+
+1999-02-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/amtoc.pl.in: minor fixes for multi-tape runs
+
+1999-02-17  Nicolas Mayencourt  <Nicolas.Mayencourt@cui.unige.ch>
+
+       * server-src/amtoc.pl.in: complete, backward-incompatible rewrite;
+       command-line arguments changed
+       * man/amtoc.8.in: ditto
+
+1999-02-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * changer-src/chg-multi.sh.in: minor portability changes
+       * docs/TAPE.CHANGERS: originally by James da Silva
+
+1999-02-17  Jean-Francois Dockes <dockes@cdkit.remcomp.fr>
+
+       * changer-src/chg-multi.sh.in: various portability changes and
+       general fixes, particularly for multieject; new cycle mode
+       * docs/TAPE.CHANGERS: detailed description of chg-multi
+       * example/chg-multi.conf: updated; added reference to
+       docs/TAPE.CHANGERS for details
+
+1999-02-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h: remove declaration of addfd.
+       * server-src/driverio.c (addfd): 2 new arguments, readset and maxfd,
+       don't use global variable.
+       * server-src/driverio.c (startup_tape_process, startup_dump_process):
+       call addfd with new argument.
+
+1999-02-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.c (startup_tape_process): new taper_program 
+       argument.
+       * server-src/driverio.h: remove declaration of taper_program.
+       * server-src/driver.c (main): declare taper_program.
+       * server-src/driver.c: call startup_tape_process with the new 
+       taper_program argument.
+       * server-src/amflush.c (run_dumps): declare taper_program.
+       * server-src/amflush.c (run_dumps): call startup_tape_process with 
+       the new taper_program argument.
+
+1999-02-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.c (startup_dump_process, startup_dump_processes):
+       new dumper_program argument.
+       * server-src/driverio.h: remove declaration of dumper_program.
+       * server-src/driver.c: declare dumper_program.
+       * server-src/driver.c: call startup_dump_process and 
+       startup_dump_processes with the new dumper_program argument.
+
+1999-02-15  Thomas Hepper <th@ant.han.de>
+
+       * changer-src/scsi-changer-driver.c forget to increment retry
+       in SCSI_* functions
+       * changer-src/chg-scsi.c (clean_tape) added sleep(60) after
+       loading the cleaning tape and before unloading
+
+1999-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/list_dir.h: remove global variable dir_list, declare
+       new function get_dir_list.
+       * server-src/list_dir.c (get_dir_list): new function to return dir_list.
+       * server-src/amindexd.c (opaque_ls): use get_dir_list.
+
+1999-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+        * server-src/holding.h: remove declaration of get_letter_from_user()
+        and select_dir().
+        * server-src/holding.c: remove function get_letter_from_user() and
+        select_dir().
+        * server-src/holding.c (pick_datestamp): return empty array instead
+        of calling exit if no directory are found.
+        * server-src/amflush.c (get_letter_from_user): new function copied
+        from holding.c.
+        * server-src/amflush.c (confirm): write a message and exit if no
+        directory were found.
+
+1999-02-14  Thomas Hepper <th@ant.han.de>
+
+       * changer-src/scsi-changer-driver.c New function SCSI_Move
+       removed move in GenericMove, call now SCSI_Move
+       Now check in GenericMove if the move is legal, based on the info
+       from the device capabilities page
+       * changer-src/scsi-linux.c (SCSI_OpenDevice) check if the device
+       is an sg device, or an link to an sg device. If no set SCSI flag to 0
+       Set timeout for SCSI commands, the default will not work if there is an
+       IES on slow changers, if not set high maschine hangs with lot of SCSI  bus
+       resets.....
+
+1999-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amindexd.c: remove duplication inclusion of version.h.
+       Include tapefile.h to get read_tapelist() prototype.
+       * server-src/amindexd.c (build_disk_table): remove a plethora of
+       unused local vars.
+       * server-src/planner.c: FORCE_FULL command was not cleared.
+
+1999-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amflush.c (flush_holdingdisk): don't update the database
+       when flushing a partial dump.
+
+1999-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.h (get_dumpfile): new function
+       * server-src/holding.c (get_dumpfile): new function to fill a
+       dumpfile_t struct from a holding file.
+
+1999-02-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amlabel.c: compiler warning: too many arguments for format
+
+1999-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amlabel.c: remove the label from the tapefile in
+       case it was already there (-f).
+
+1999-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c: make sure holding files are not larger
+       that chunksize.
+
+1999-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcleanupdisk.c: new program to scan and find temporary
+       file on holding disks.
+       * server-src/Makefile.am (libexec_PROGRAMS): add amcleanupdisk.
+       * server-src/amcleanup.sh.in: call amcleanupdisk.
+
+1999-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.c (pick_all_datestamp): new function to return
+       all datestamp in the holding disks.
+       * server-src/holding.h: declare pick_all_datestamp.
+
+1999-02-13  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/diskfile.h (host_t): new start_t field.
+       * server-src/diskfile.c (read_diskline): set start_t to 0.
+       * server-src/driver.c (start_some_dumps): Don't start a dump if 
+       the host->start_t > now.
+       * server-src/driver.c (start_some_dumps): set host->start_t to 15 sec 
+       in the future when starting a FILE_DUMP.
+       * server-src/driver.c (dump_to_tape): set host->start_t to 15 sec in 
+       the future when starting a PORT_DUMP.
+
+1999-02-12  Thomas Hepper <th@ant.han.de>
+       * changer-src/Makefile.am added tape-src to the include list
+       * changer-src/chg-scsi.c removed the changes for not using the
+       statfile.
+       * changer-src/scsi-aix.c Added debug output in SCSI_ExecuteCommand
+       added size parameter to the SCSI_Inquiry call
+       * changer-src/scsi-bsd.c added size parameter to the SCSI_Inquiry call
+       * changer-src/scsi-hpux_new.c same as above 
+       * changer-src/scsi-irix.c same as above
+       * changer-src/scsi-solaris.c same as above
+       * changer-src/scsi-linux swich from ioctl interface to sg interface.
+       Not full tested yet !!
+       * changer-src/scsi-changer-driver.c Added new structs for new devices.
+       complete rewrite of Sense Handling. Removed now unused functions.
+       Added first functions for Barcode reader support.
+       Now use MODE_SENSE to get the number of Drives/Slots/Robots.
+       Split up functions in SCSI functions (prefix SCSI, Generic functions,
+       prefix Generic. Not complete yet). Rewrite of GenericElementStatus
+       * changer-src/scsi-defs.h added new structs, reordered some defines.
+       * changer-src/chg-scsi-chio.c New file(copy of chg-scsi.c). 
+       Too difficult to maintain chg-scsi and chg-scsi-chio from one file
+
+1999-02-10  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/amlabel.c (main): try to read just-written tape label
+       back; if wrendmark overwrote the label, suggest using a
+       non-rewinding device
+       * tape-src/tapeio.c (tape_wrendmark): would not close tape device if 
+       wrendmark failed
+
+1999-02-10  Paul Bijnens  <Paul.Bijnens@lant.be>
+
+       * server-src/amoverview.pl.in: Y2K fix in output to user
+       * server-src/amtoc.pl.in (print_info): ditto
+
+1999-02-10  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c (getsize_dump): do not redirect standard
+       output of estimator to /dev/null if we HAVE_DUMP_ESTIMATE
+
+1999-02-03  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * NEWS: fix description of incronly: it won't really perform full
+       backups
+
+       * NEWS: support for ufsdump -S, incronly strategy and new chunksize
+       default
+
+       * server-src/conffile.c (init_holdingdisk_defaults, chunksize):
+       default to 1Gb
+       * example/amanda.conf.in: ditto
+       * man/amanda.8.in: ditto
+
+       * configure.in (amanda_cv_dump_estimate): check for support for -S
+       too, and define HAVE_DUMP_ESTIMATE as the estimate switch, if any
+       * client-src/sendsize.c (re_size): new regexps for Solaris ufsdump
+       -S and Samba `du'.  Restrict regexp that matched Digital Unix'
+       dump -E so that it doesn't match smbclient's output any more.
+       Move some regexps around, and only define them if the corresponding
+       dump program is available
+
+1999-02-01  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * example/amanda.conf.in: document the behavior of relative
+       exclude-list files
+       * man/amanda.8.in: ditto
+
+       * man/amanda.8.in (exclude list): the GNU tar flag is
+       --exclude-from, not --exclude-list
+       Reported by Tom Schutter <tom@platte.com>
+
+1999-02-01  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendbackup-gnutar.c (re_table): ignore `session request 
+       to' message printed by Samba 2.0.0
+
+1999-01-28  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/amanda.8.in (comprate): it is not used when there is history
+       information; useful for large disks that compress little
+       Reported by job bogan <job@piquin.uchicago.edu>
+
+1999-01-28  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * Makefile.am: select which SUBDIRS to descend to here
+       * client-src/Makefile.am: removed if WANT_CLIENT
+       * tape-src/Makefile.am: removed if WANT_TAPE
+       * server-src/Makefile.am: removed if WANT_SERVER
+       * changer-src/Makefile.am: ditto
+       * restore-src/Makefile.am: removed if WANT_RESTORE
+       * recover-src/Makefile.am: removed if WANT_RECOVER
+       * amplot/Makefile.am: removed if WANT_AMPLOT
+
+1999-01-27  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * NEWS: chg-scsi ports and Samba 2.0.0 support
+
+       * configure.in (USE_AMANDAHOSTS): enable by default
+       * example/config.site: ditto
+       * docs/INSTALL: ditto
+       * NEWS: ditto
+
+       * docs/INSTALL: updated URLs for GNU packages and Samba
+       * docs/SAMBA: note that Samba 2.0.0 is supported
+
+       * docs/SYSTEM.NOTES (HP/UX): what does `Link severed' mean?
+
+1999-01-27  Thomas Hepper <th@ant.han.de>
+       * changer-src/scsi-changer-driver.c SCSI_ReadElementStatus
+       A while loop has to start with while, not if .....
+
+1999-01-27  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * Makefile.am (EXTRA_DIST): sst was added within contrib
+
+       * ltmain.sh, ltconfig, libtool.m4i: updated from libtool CVS
+       * configure.in: AC_SUBST LIBTOOL_DEPS
+       * Makefile.am: regen libtool if neded
+
+       * Makefile.am: declare that we want automake 1.4 and we're a foreign 
+       package
+
+       * configure.in: require autoconf 2.13, and use
+       AC_VALIDATE_CACHED_SYSTEM_TUPLE instead of
+       AC_VALIDATE_CACHE_SYSTEM_TYPE
+       * config/acinclude.m4i: removed AC_VALIDATE_CACHE_SYSTEM_TYPE
+
+       * configure.in (SAMBA_CLIENT): updated check for smbclient to
+       support Samba 2.0.0
+
+1999-01-26  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/amdump.sh.in (runuser): set to LOGNAME if defined, and
+       to the output of whoami otherwise
+       Reported by Tom Schutter <tom@platte.com>
+
+1999-01-26     Thomas Hepper <th@ant.han.de>   
+       * Makefile.am Added sst driver files to EXTAR_DIST
+
+1999-01-26     Thomas Hepper <th@ant.han.de>   
+       * changer-src/chg-scsi.c If statfile is not set try to get the info
+       about the current loaded tape direct from the changer.
+       Fixed debug output for the eject value if > 1
+       * changer-src/libscsi.h Prototype for GetCurrentSlot
+       * changer-src/scsi-aix.c If the Device we open is not a changer or tape
+       return NULL, so that the above function can abort. New eject per mtio ioctl.
+       * changer-src/scsi-bsd.c see scsi-aix.c
+       * changer-src/scsi-linux.c see scsi-aix.c
+       * changer-src/scsi-hpux_new.c see scsi-aix.c
+       * changer-src/scsi-irix.c see scsi-aix.c
+       * changer-src/scsi-solaris.c see scsi-aix.c and added a retry loop for
+       the execution of SCSI commands.
+       * changer-src/scsi-changer-driver.c New Function SCSI_ReadElementStatus
+       split ReadElementStatus in device and device independed part
+       New EXB120ElementStatus, renamed ReadElementStatus in GenericElementStatus
+       added EXB 120 and DLT7000 to the devices list.
+       Removed the linked list for the element status. Now every element
+       type has its own array allocated in the *ElementStatus functions.
+       Check in the functions which sends SCSI commands if the fd is able to
+       receive SCSI commands.
+       In GenericEject check which type of eject to use (ioctl/SCSI)
+       New GetCurrentSlot, try to get the info about the loaded tape direct from
+       the changer.
+       * changer-src/scsi-chio.c Add function GetCurrentSlot (not well tested yet)
+       * changer-src/scsi-defs.h Added missing decl. in MediumTransportElementDescriptor_T
+       for LITTLE_ENDIAN_BITFIELDS
+       new field from in ElementInfo_T
+       * changer-src/sci-hpux.c EMpty function GetCurrentSlot, do we still need scsi-hpux.c ?
+       * docs/TAPE.CHANGERS added some notes for HP-UX, expanded list of tested devices
+       
+1999-01-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.c (init_defaults): default value of runspercycle
+       is 0.
+       * server-src/amadmin.c (balance): use default value of runspercycle.
+       * server-src/planner.c (main): use default value of runspercycle.
+
+1999-01-22  Martin Apel <apel@tecmath.de>
+
+       * example/amanda.conf.in: explanation of incronly strategy.
+       * man/amanda.8.in: explanation of incronly strategy.
+       * server-src/amadmin.c: recognize incronly strategy
+       * server-src/conffile.c: read the incronly strategy in the
+       configuration file.
+       * server-src/conffile.h: definition of DS_INCRONLY
+       * server-src/planner.c: Do planning for incronly strategy:
+       If the force flag is set perform a full dump, otherwise do
+       normal incremental processing but avoid full dumps.
+       * server-src/tapefile.c: Bugfix so only tapes which match
+       the regular expression for tape labels in the current 
+       configuration are considered for writing.
+
+1999-01-22  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in: require autoconf 2.12.2
+
+       * changer-src/Makefile.am (LDADD): add libamtape, because
+       tapefd_rdlabel() is used in scsi-changer-driver.c
+
+       * server-src/planner.c (output_scheduleline): removed `or historical
+       data' from `no estimate' message; historical data doesn't matter any 
+       more
+       Reported by Giorgos Vlachos <Giorgos.Vlachos@eurodyn.com>
+
+1999-01-20  Todd Pfaff  <pfaff@mcmaster.ca>
+       
+       * client-src/sendbackup-gnutar.c: more Samba 2.0.0 messages
+
+       * client-src/sendbackup-gnutar.c: new Samba 2.0.0 message 
+
+1999-01-19  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amflush.c: use ap_snprintf instead of snprintf.
+       * server-src/amflush.c: rotation of new amflush log was broken.
+
+1999-01-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: always call output_stats(), the problem is
+       that degraded_mode is set if amflush fills the tape.
+
+1999-01-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amflush.c: write debuging info to $logdir/amflush
+       instead of /dev/null if we run in background.
+       * server-src/amcleanup.sh.in: rename $logdir/amflush.
+
+1999-01-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: fix a divide by zero error.
+
+1999-01-10  Thomas Hepper <th@ant.han.de>
+        * rewite of the scsi-changer-driver.c and the os depnedent
+          parts. Removed one layer of functions (Move, Eject, Clean ...)
+
+1999-01-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: report the current dump when reporting
+       the busy time of each dumper.
+
+1998-12-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c: open temporary holding file with O_TRUNC flags
+       and with mode 0600.
+
+1998-12-28  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/reporter.c: do not drop core generating labels if the
+       tape label is not defined, e.g. in degraded mode (compliments of
+       Jan L. Peterson <jlp@Part.NET>).
+
+1998-12-28  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amtape.c: initialize two strings to NULL to avoid a
+       core dump, compliments of G. Allen Morris III <gam3@acm.org>.
+
+1998-12-27  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amreport.8.in: remove reference to 8.5x11 paper size for the
+       3-hole binder.
+
+1998-12-27  John R. Jackson  <jrj@purdue.edu>
+
+       * example/3hole.ps: new lbl-templ file for 3 hole punch reports
+       * example/Makefile.am: add 3hole.ps
+
+1998-12-22  Thomas Hepper <th@icem.de>
+
+       * docs/TAPE.CHANGERS Update notes about chg-scsi
+       * changer-src/chg-scsi.c Added new config option tapestatus,
+       if set the tape log pages are written to this file.
+       changed parameter list for get_clean_state/ask_clean,
+       * changer-src/libscsi.h changed parameter list for get_clean_state
+       * changer-src/scsi-changer-driver.c Added new functions OpenDevice
+       CloseDevice LookupDevice. 
+       Added new functions to read and decode the Tape LOG Pages.
+       Tape Eject and ready check is now done by SCSI calls
+
+       * changer-src/scsi-aix.c
+       * changer-src/scsi-bsd.c
+       * changer-src/scsi-hpux_new.c
+       * changer-src/scsi-hpux.c
+       * changer-src/scsi-irix.c
+       * changer-src/scsi-solaris.c
+       Changed all SCSI_OpenDevice/SCSI_CloseDevice functions so that they
+       fit to the new OpenDevice/CloseDevice calls. Removed mtio.h from 
+       includes, remove Tape_Ready and Tape_Eject
+       * changer-src/scsi-chio.c
+       * changer-src/scsi-defs.h
+
+       For all changer-src files, removed tabs, run indent (from xemacs)
+       Added emacs variables to the end (no tab, gnu style)
+
+1998-12-21  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amanda.8.in: document the lbl-templ tapetype option.
+
+1998-12-21  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amreport.8.in: fix formatting problem.
+
+1998-12-20  John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: define NEED_RESETOFS unless LFS (large file system
+       support) is available.
+       * config/acconfig.h: add NEED_RESETOFS tag.
+       * server-src/taper.c: only reset the tape offset if NEED_RESETOFS
+       is defined and only once per 2 GBytes.
+
+1998-12-20  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/amlabel.c (main): datestamp for new tapes is now 0
+       * server-src/tapefile.c (reusable_tape): recognize datestamp 0 as
+       reusable
+       * man/amlabel.8.in: document that tapes are added to tapelist
+
+1998-12-19  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: instead of just displaying why no
+       dumpers were busy, display reason(s) why N+1 were not busy.
+
+1998-12-18  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: add statistics about how much time
+       taper and each dumper is busy, how much time N dumpers are busy
+       and why no dumpers were busy.
+
+1998-12-18  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: fix two perl warnings.
+
+1998-12-18  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: fix two minor typos.  Add percentage
+       display to the summary comparing real and estimated size and real
+       versus total estimate (showing how well the estimates are doing and
+       a rough guess at how far along the run is).  Also the percentage of
+       total holding disk space in use.
+
+1998-12-18  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: take the --file argument as is if it
+       is an absolute path.
+
+1998-12-18  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c: call short_dump_state() one last time before
+       quitting so amstatus gets a last good status.  Tell taper to quit
+       after the dumpers since it writes more information to the amdump
+       file (helps prevent mixed messages).
+
+1998-12-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * common-src/Makefile.am (noinst_DATA): removed; bogus
+       * config/config.guess, config/config.sub: config/install-sh,
+       config/mkinstalldirs: updated to current pre-2.13 autoconf CVS tree
+       * patches/autoreconf.patch: removed
+       * config/libtool/libtool.m4: renamed to config/libtool.m4i
+       * config/acinclude.m4: renamed to config/acinclude.m4i
+       * config/Makefile.am (EXTRA_DIST): updated to reflect changes
+       * autogen: build config/acinclude.m4  by concatenating acinclude.m4i
+       and libtool.m4i
+       * configure.in: no longer test whether libtool is installed; require 
+       newer autoconf
+       * config/ltconfig, config/ltmain.sh, config/libtool.m4i: updated to
+       libtool 1.2d
+       * amplot/Makefile.am (EXTRA_DIST): no longer needed
+       * changer-src/Makefile.am (chg_scsi_SOURCE): move scsi-defs.h closer 
+       to the beginning of the list
+       * docs/INSTALL: fixed URL to gnuplot; recommend autoconf and
+       automake from CVS
+
+1998-12-14  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (BSD SCSI): test ... -a ... is not portable, and less 
+       so when written test ... -a test ... :-)
+
+1998-12-14  Thomas Hepper <th@icem.de>
+
+       * changer-src/Makefile.am Added scsi-bsd.c
+       * changer-src/chg-scsi.c Initialize *scsitapedevice
+       * changer-src/scsi-changer-driver.c remove LITTLE_ENDIAN_BITFILEDS
+       defenition
+       changed RequestSense to pRequestSense (there is a function 
+       called RequestSense)
+       changed error handling in ResetStatus (fix for IRIX)
+       FIxed length handling for the pages in ReadElemtStatus
+       * changer-src/scsi-chio.c get_clean_state only returns 0, the
+       ioctl to get the clean flag is not portable ;-(
+       changed all (f)printf to dbprintf
+
+       * changer-src/scsi-defs.h ElementStatusData_T is for BIG and
+       LITTLE endian the same ...
+
+       * changer-src/scsi-bsd.c New file for FreeBSD
+
+       * changer-src/scsi-irix.c Clean up in the return handling
+       changed RequestSense to pRequestSense
+       Removed unused function TapeStatus
+
+       * changer-src/scsi-linux.c changed RequestSense to pRequestSense
+       Removed unused function TapeStatus
+
+       * changer-src/scsi-solaris.c changed RequestSense to pRequestSense
+       Removed unused function TapeStatus
+
+       * config/acconfig.h added def for BSD_LIKE_SCSI
+
+       * configure.in Added check for ENDIAN type AC_C_BIGENDIAN
+       added sys/scsiio.h and check for BSD SCSI interface
+
+1998-12-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (handle_dumper_result): rename .tmp files
+       when receiving ABORT_FINISHED.
+
+1998-12-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (start_some_dumps): Use the holdp returned
+       by find_diskspace for a big_dumper in degraded mode.
+
+1998-12-11  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SYSTEM.NOTES (Ultrix): recommend gcc or egcs
+       (IRIX): patch for xfsdump estimates
+
+1998-12-10  John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/amflock.c (main): remove call set_pname() for
+       CONFIGURE_TEST since error.o is not linked in.
+
+1998-12-10  John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/amflock.c (main): report CONFIGURE_TEST error messages to
+       stderr.
+
+1998-12-10  John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/amflock.c (main): call set_pname() for CONFIGURE_TEST.
+       * configure.in: do not set up pname global for lnlock CONFIGURE_TEST.
+
+1998-12-09  Henning P. Schmiedehausen  <henning@tanstaafl.de>
+
+       * client-src/sendbackup.c (parse_options): Added check whether the
+       pathname of the exclude file is relative and if yes, use the
+       mountpoint of the filesystem as anchor.  So you can put your exclude
+       file in the root of the filesystem to backup.
+       * client-src/sendsize.c (getsize_gnutar): added the same check as
+       above so sendsize uses the same exclude file.
+
+1998-12-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.c (size_holding_files): return size in KB.
+       * server-src/driver.c (adjust_diskspace): use KB returned by
+       size_holding_files.
+       * server-src/driver.c: rename .tmp file
+       * server-src/dumper.c: do not rename .tmp file. let the driver do it.
+
+1998-12-09  John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/stream.c (stream_server): do not request a reserved port
+       if we are root but PORTRANGE is defined.  Also, clean up the code
+       and make sure *portp is -1 on all error returns.
+
+1998-12-08  John R. Jackson  <jrj@purdue.edu>
+
+       * Makefile.am: add the user-contributed area.
+       * contrib/README: describe the user-contributed area.
+       * contrib/dbbackup.README: README for Oracle database backup system.
+       * contrib/dbbackup.ksh: Oracle database backup system wrapper.
+       * contrib/dbbackup.sql: Oracle database backup system setup commands.
+       * contrib/dbbackup.tcl: Oracle database backup system main body.
+
+1998-12-08  John R. Jackson  <jrj@purdue.edu>
+
+       * amplot/Makefile.am: fix install rule when DESTDIR is non-null,
+       compliments of Henning P. Schmiedehausen <hps@tanstaafl.de>.
+
+1998-12-08  John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: fix reversed code for --with-amrecover, compliments
+       of Yar Tikhiy <yar@radio-msu.net>.
+
+1998-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * common-src/fileheader.h (dumpfile_t): new is_partial field.
+       * common-src/fileheader.c: add codee for new is_partial field.
+       * server-src/holding.h (rename_tmp_holding): declare new function.
+       * server-src/holding.c (rename_tmp_holding): new function.
+       * server-src/dumper.c (do_dump): return 1 if succeded, otherwise 0.
+       * server-src/dumper.c (main): open .tmp when dumping to disk, 
+       rename .tmp if do_dump return 1.
+       * server-src/dumper.c (update_dataptr): open .tmp for new chunk.
+       * server-src/amstatus.pl.in (dump_size): return size of .tmp file.
+
+1998-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * NEWS: document new force-bump, force-no-bump and unforce-bump 
+       command in amadmin.
+
+1998-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.c (size_holding_files): new function to
+       return the sum of the size of all chunk of an image.
+       * server-src/holding.h (size_holding_files): declare.
+       * server-src/driver.c (adjust_diskspace): use size_holding_files 
+       instead of doing a stat of only the first chunk.
+
+1998-12-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c: new force-bump, force-no-bump and unforce-bump
+       command.
+       * man/amadmin.8.in: document them.
+
+1998-12-05  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ (large filesystems): fixed reference to results missing
+       (results missing): updated to 64Kb UDP packets
+
+1998-12-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/infofile.h: rename PLANNER_FORCE to FORCE_FULL
+       * server-src/planner.c: rename PLANNER_FORCE to FORCE_FULL
+       * server-src/amadmin.c: rename PLANNER_FORCE to FORCE_FULL
+
+1998-12-01  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcheck.c: make -t mean do the tape checks, add new -l
+       option for doing just the local server (non-tape) checks.  Have -w
+       turn on -t.  Have -cs (or -sc) do both server and client checks.
+       * man/amcheck.8.in: document above changes and clean up some minor
+       formatting issues.
+
+1998-11-30  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (start_some_dumps): In degraded mode,
+       a big dumper should do high priority dump before low priority.
+       * server-src/driver.c (sort_by_priority_reversed): sort by
+       time if priority is equal.
+
+1998-11-28  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/infofile.h: declare FORCE_BUMP and FORCE_NO_BUMP
+       as command.
+       * server-src/amadmin.c (force_one,unforce_one,info_one): work
+       with info.command with bit operator.
+       * server-src/planner.c (setup_estimate): work with info.command 
+       with bit operator, support for FORCE_BUMP and FORCE_NO_BUMP command.
+
+1998-11-27  Thomas Hepper    <th@icem.de>
+
+       * changer-src/scsi-aix.c Some changes in the error handling in
+       scsi command execution
+       * changer-src/scsi-changer-driver.c More debug prints.
+       removed Endian16/Endian24 (replaced with macros)
+       * changer-src/scsi-chio.c make get_clean_state work on linux
+       * changer-src/scsi-defs.h  added macros for converting from/to
+       SCSI CDB MSB type
+       * docs/TAPE.CHANGERS add note about AIX and chg-scsi
+
+1998-11-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c(export_one): export the last_level and
+       consecutive_runs field.
+       * server-src/amadmin.c(import_one): import the last_level and
+       consecutive_runs field.
+
+1998-11-24  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amlabel.c: insist on being run as the dump user (ala
+       amlabel) to keep permissions straight.
+
+1998-11-24  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amadmin.c: fix minor message format problem.
+
+1998-11-24  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amlabel.c: insist on being run as the dump user (ala
+       amflush) to keep permissions straight.
+
+1998-11-24  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amrmtape.sh.in: insist on being run as the dump user (ala
+       amdump) to keep permissions straight.
+
+1998-11-24  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amadmin.c: issue a warning for update commands that might
+       leave ownership incorrect.
+
+1998-11-24  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcheck.c: add a "-t" option to disable tape tests in the
+       server checks.  This lets server checks be done without mounting a
+       tape.  Add lots more sanity checks, in particular, ownership and
+       permissions of the index area and text format database.  Warn if
+       amcheck is not run as the dump user listed in amanda.conf.  Minor
+       consistency cleanup in the messages.
+       * man/amcheck.8.in: document the changes.
+
+1998-11-20  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/amcleanup.sh.in (logdir/amdump): arrange that it is
+       renamed if it exists, even if no log file could be found.
+
+1998-11-19  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * config/ltmain.sh, config/ltconfig, config/libtool/libtool.m4:
+       updated to current CVS libtool
+
+1998-11-19  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/conffile.c (get_holdingdisk, init_holdingdisk_defaults):
+       set the default chunksize and the "0" and "-1" special chunksizes
+       to 64 KBytes less than the maximum to allow the final read at EOF.
+       * server-src/dumper.c (main): leave the chunksize as it is when it
+       comes in except to truncate it to a 32 KByte boundary.
+       * man/amanda.8.in: add some chunksize comments and clean up a few
+       minor odds and ends.
+
+1998-11-19  John R. Jackson  <jrj@purdue.edu>
+
+       * recover-src/amrecover.c (main): use set_host to find the initial
+       host name so we get the same alias resolution at startup as the
+       sethost command.
+       * recover-src/set_commands.c (set_host): report alternate names being
+       attempted and only clear the directory list if a host is found.
+
+1998-11-19  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/driverio.c (update_info_dumper): do not update
+       compression or dump rates when called from
+       update_failed_dump_to_date
+       Reported by Michael Schmitz <mschmitz@sema.de>
+
+1998-11-18  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c (main): reduce the size of the chunksize by
+       2 blocks.
+
+1998-11-18  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in: hack for paxutils was not working; fixed
+
+1998-11-18  Michael Povel  <mcp@ladyada.han.de>
+
+       * server-src/changer.h added new functions:changer_query
+       ,changer_search,changer_find, changer_label
+       * server-src/changer.c added changer_query, changer_search,
+       changer_find, changer_label
+       * server-src/amcheck.c (taper_scan) now uses changer_find 
+       * server-src/amtape.c (load_label and taper_scan) now use changer_find
+       * server-src/taper.c (taper_scan) now uses changer_find
+       * server-src/amlabel.c (main) added call to changer_label
+       which is only an empty dummy at the moment
+
+1998-11-18  Thomas Hepper <th@icem.de>
+
+       * changer-src/chg-scsi.c Added debug print option
+       * changer-src/chg-scsi.c If the load fails do not continue
+       * changer-src/scsi-aix.c changed #include <config.h> to <amanda.h>
+       * changer-src/scsi-aix.c Added debug prints to SCSI_ExecuteCommand
+       * changer-src/scsi-changer-driver.c changed #include <config.h> to 
+       #include <amanda.h>
+       * changer-src/scsi-changer-driver.c Added debugging prints
+       * changer-src/scsi-changer-driver.c Remove unused funktion TestUnitReady
+       * changer-src/scsi-chio.c added missing funktion Tape_Ready
+       * changer-src/scsi-hpux.c removed #include "config.h", is already done
+       in amanda.h
+       * changer-src/scsi-hpux_new.c  changed #include <config.h> to 
+       #include <amanda.h>
+       * changer-src/scsi-irix.c changed #include <config.h> to 
+       #include <amanda.h>
+       * changer-src/scsi-linux.c changed #include <config.h> to 
+       #include <amanda.h>
+       * changer-src/scsi-solaris.c changed #include <config.h> to 
+       #include <amanda.h>
+
+1998-11-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c: disable HAVE_DUMP_ESTIMATE if SAMBA_CLIENT
+       is defined
+
+1998-11-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/tapefile.c (lookup_last_reusable_tape): Wrong order
+       to shift the tpsave array.
+
+1998-11-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * example/amanda.conf.in: document that infofile is supposed to be a
+       directory with the default database format
+       * docs/FAQ: New questions: `infofile update failed' and `using the
+       same host in different configurations'
+
+1998-11-17  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       changer-src/scsi-linux.c (Tape_Ready): typo, the argument Device
+       to the SCSI_CloseDevice() is not defined, I changed it to tapedev.
+
+1998-11-17  Brendan M Coffey <bcoffey@connix.com>
+
+       * common-src/stream.c (stream_server): add requested send and receive
+       socket size parameters.
+       * common-src/stream.h (stream_server): ditto
+       * server-src/taper.c (file_reader_side): set a large receive socket
+       buffer size.
+       * client-src/sendbackup.c (main): set a large send and receive socket
+       buffer size for the data path, use defaults for the message and index
+       paths.
+
+1998-11-16  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * changer-src/scsi-solaris.c (Tape_Ready): typo in Thomas' patch
+
+1998-11-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/infofile.h (get_dumpdate): rename record parameter to info.
+       * server-src/infofile.h (get_info): rename record parameter to info.
+       * server-src/infofile.h (put_info): rename record parameter to info.
+       * server-src/infofile.c (get_dumpdate): rename rec parameter to info.
+       * server-src/infofile.c (zero_info): rename ip parameter to info.
+       * server-src/infofile.c (get_info): rename record parameter to info.
+       * server-src/infofile.c (put_info): rename record parameter to info.
+       * server-src/infofile.c (dump_rec): rename r parameter to info.
+       * server-src/infofile.c (dump_db): rename record variable to info.
+       * server-src/planner.c (last_level): rename ip parameter to info.
+       * server-src/planner.c (next_level0): rename ip parameter to info.
+       * server-src/planner.c (runs_at): rename ip parameter to info.
+       * server-src/planner.c (askfor): rename inf parameter to info.
+       * server-src/planner.c (setup_estimate): rename inf variable to info.
+       * server-src/driverio.c (update_info_dumper): rename inf parameter 
+       to info.
+       * server-src/driverio.c (update_info_taper): rename inf parameter 
+       to info.
+       * server-src/amadmin.c (next_level0): rename ip parameter to info.
+       * server-src/amadmin.c (force_one): rename inf variable to info.
+       * server-src/amadmin.c (unforce_one): rename inf variable to info.
+       * server-src/amadmin.c (delete_one): rename inf variable to info.
+       * server-src/amadmin.c (info_one): rename inf variable to info.
+       * server-src/amadmin.c (due_one): rename inf variable to info.
+       * server-src/amadmin.c (balance): rename inf variable to info.
+
+1998-11-11  Thomas Hepper <th@icem.de>
+
+       * configure.in: amanda_cv_hpux_scsi was double defined.
+       Replaced it in the chio check with amanda_cv_hpux_scsi_chio
+       * docs/TAPE.CHANGERS: update the notes about chg-scsi
+       * changer-src/chg-scsi.c: Unload the cleaning tape only
+       if it is loaded
+       Pass the changerdev and tapedev Tape_Ready, so we can check
+       if changerdev=tapedev. In this case the fd is already open.
+       * changer-src/scsi-aix.c: cleanup and first parts are running :-)
+       * changer-src/scsi-changer-driver.c: Pass back the scsi status
+       field to the calling function, not the result from the ioctl
+       if the return form the ioctl is >= 0
+       * changer-src/scsi-hpux.c: Add additional param to Tape_Ready
+       fill Tape_Ready with live 
+       * changer-src/scsi-hpux_new.c: Return the scsi status if 
+       the ioctl result is >=0. Add new Parameter to Tape_Ready
+       * changer-src/scsi-irix.c: same as scsi-hpux_new.c
+       * changer-src/scis-linux.c: Add additional param to Tape_Ready
+       * changer-src/scsi-solaris.c: same as scsi-hpux_new.c
+
+1998-11-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (main): redo my patch about total_disksize that
+       Alexendre has undone, only the 2.4.1 branch was broken.
+
+1998-11-10  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/driver.c (main): total_disksize was only added after
+       the loop terminated, i.e., when hdp was NULL -> crash.  fixed.
+
+1998-11-09  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/reporter.c (main): ignore SIGPIPE so if a child process
+       dies we do not also go away.  Also fix a core dump if amanda.conf
+       cannot be processed, and clean up a few error messages.
+
+1998-11-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/infofile.h (struct info_s): add last_level and
+       consecutive_runs.
+       * server-src/infofile.c: support new last_level and consecutive_runs
+       * server-src/planner.c (last_level): return ip->last_level.
+       * server-src/planner.c (runs_at): return ip->consecutive_runs.
+       * server-src/driverio.c (update_info_dumper): update inf.last_level
+       and inf.consecutive_runs.
+
+1998-11-09  Mike Grupenhoff <kashmir@munge.com> 
+       * client-src/sendbackup-dump.c (start_backup): don't close indexf
+       if it was never open
+       * client-src/sendbackup-gnutar.c (start_backup): ditto
+
+1998-11-08  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (main): add hdp->disksize to total_disksize
+       even when we create the datestamp dir. (reserve was unusable).
+
+1998-11-07  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (GNUTAR): accept tar from Free paxutils, the new name
+       of GNU tar
+
+1998-11-07  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * changer-src/scsi-solaris.c: added missing #endif
+
+       * configure.in: merge with camlib.h patch from Oct 31.
+       remove all uses of test ... -a ...; this is not portable.
+       (AC_CHECK_HEADERS) added header files for Linux and Solaris
+
+1998-11-07  Thomas Hepper  <th@icem.de>
+
+       * changer-src/chg-scsi: Add config option scsidev
+       * changer-src/chg-scsi: Remove function tape_ready
+       * changer-src/chg-scsi: Add new parameter tapedev to function
+       ask_clean
+       * changer_src/scsi-hpux.c: changed HAVE_HPUX_SCSI to 
+       HAVE_HPUX_SCSI_CHIO, changed in configure.in too
+       * changer-src/libscsi.h: Expand definition for get_clean_state
+       * new files in /changer-src:
+       scsi-aix.c, scsi-changer-driver.c, scsi-defs.h
+       scsi-hpux_new.c, scsi-irix.c, scsi-linux.c, scsi-solaris.c
+       * configure.in checks for scsi ioctl added, check for header files
+       for the scsi suport added
+       * config/acconfig.h new:
+       HAVE_HPUX_LIKE_SCSI, HAVE_HPUX_SCSI_CHIO, HAVE_LINUX_LIKE_SCSI
+       HAVE_IRIX_LIKE_SCSI, HAVE_SOLARIS_LIKE_SCSI, HAVE_AIX_LIKE_SCSI
+              removed: HAVE_HPUX_SCSI
+       * changer-src/Makefile.am: New conditional for building chg-scsi-chio
+       and chg-scsi. chg-scsi-chio is the old chg-scsi
+
+1998-11-05  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amverify.sh.in: tolerate extra amtape output.
+
+1998-11-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/amrecover.c: remove declaration of errstr.
+
+1998-11-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amindexd.c (build_disk_table): call find_dump() instead
+       of popen("amadmin <conf> find ...")
+
+1998-11-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.h: rename dir_list to holding_list because
+       dir_list is also declared in amflush.c
+       * server-src/holding.c: ditto
+       * server-src/find.c: ditto
+
+1998-11-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: remove warning.
+
+1998-11-04  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/taper.c (read_file): if a new tape cannot be found,
+       report a no-tape error to the log file and exit, just like it does
+       for the first tape
+
+1998-11-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (pick_inclevel): return base_level even
+       when the estimate failed.
+       * server-src/planner.c (output_scheduleline): test for degr_size
+       instead of degr_level.
+
+1998-11-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (last_level): update last_date otherwise only
+       level 0 or the highest is returned.
+
+1998-11-03  Mike Grupenhoff  <kashmir@munge.com>
+
+       * common-src/alloc.c: const arguments to the stralloc functions
+       * common-src/amanda.h: update stralloc prototypes for const
+       poisoning
+
+1998-11-03  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/dumper.c (do_dump): do not report FAILED back to driver
+       when it sent us ABORT.  Clean up and send back ABORT-FINISHED.
+
+1998-11-03  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c (handle_dumper_result): do not abort a dumper
+       that reports NO-ROOM if taper is busy since some holding disk space
+       will eventually be released (this code it not used when PORT-DUMP is
+       in progress).
+
+1998-11-03  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/taper.c (write_buffer): calling lseek after every tape
+       write is wasteful and makes utilities like lsof less useful.  Only
+       reset the offset when the amount written is about to go over 2 GBytes.
+
+1998-11-02  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driver.c (main, start_degraded_mode): fix rounding problem
+       that made the code think there was a little room for full dumps in
+       degraded mode, and fix the code that decides whether to do a full dump
+       in degraded mode.
+
+1998-11-02  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amstatus.pl.in: initialize variable to remove warning.
+
+1998-11-02  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/Makefile.am (CLIENT_SCRIPTS): rename to
+       CLIENT_SCRIPTS_OPT, because *_SCRIPTS is interpreted by automake
+       * configure.in (CLIENT_SCRIPTS): ditto
+       Reported by Thomas Hepper <Thomas.Hepper@icem.de>
+
+       * configure.in (LIBTOOL_M4): no longer defined
+       (LIBTOOL_M4_MACRO_DIR): defined assuming CWD is top_srcdir
+       * Makefile.am (ACLOCAL_M4_FROM_SRCDIR): relative to srcdir
+       (ACLOCAL_M4): defined and created using ACLOCAL_M4_FROM_SRCDIR
+       Reported by Thomas Hepper <Thomas.Hepper@icem.de>
+       
+       * client-src/sendbackup.c (backup_program): rename to
+       gnutar_program, that's the name it should have had from the
+       beginning
+       * client-src/sendbackup-gnutar.c (backup_program): ditto
+
+1998-10-31  Michael Schmitz <mschmitz@iname.com>
+
+       * configure.in: let configure check whether strcasecmp is
+       present
+       * common-src/strcasecmp.c: new file which contains a definition
+       of strcasecmp
+       * common-src/amanda.h: added code to declare strcasecmp in
+       case it's not declared in a standard header
+
+1998-10-31  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (snprintf): arrange that it is included in the
+       distribution automatically
+       * common-src/Makefile.am (EXTRA_DIST): removed, not needed
+
+       * changer-src/Makefile.am (libexec_SCRIPTS): would only be enabled
+       if WANT_CHG_SCSI
+
+       * configure.in (NO_SCSI_CHANGER_MODE): chg-scsi does not support the
+       new FreeBSD 3.0 chio.h, so disable it if camlib.h is found.
+       * docs/SYSTEM.NOTES (FreeBSD 3.0): add a note about this
+       (SunOS 4.x): libtool will no longer find incorrect library versions
+
+1998-10-30  John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/security.c (bsd_security_ok): change error message to
+       reflect that it is a host name we were looking up rather than an
+       address (also makes the two similar messages unique).
+
+1998-10-28  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SYSTEM.NOTES: Debian 2's dump uses /var/lib/dumpdates 
+
+1998-10-28  John R. Jackson  <jrj@purdue.edu>
+
+       * recover-src/set_commands.c (set_host): if the host given by the user
+       does not work, try the canonical name and aliases returned by
+       gethostbyname.
+
+1998-10-28  John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: use "df /" instead of just "df" when trying to find
+       the device that has the root file system to avoid things like NFS
+       hangs that df sometimes suffers from.
+
+1998-10-27  Mike Grupenhoff <kashmir@munge.com>
+
+       * common-src/stream.c (stream-client): add a 'localport' argument
+       in which we can get the port this stream is bound to locally
+       * common-src/stream.h (stream-client): update prototype
+       * server-src/dumper.c: update stream-client calls
+
+1998-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/amandad.c (main): better logging of received packet,
+       do not send a P_ACK when the received packet is not a P_REQ.
+
+1998-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/amandad.c (main): terminate immediately if started
+       by a P_ACK packet without sending a P_NAK packet.
+
+1998-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.h (dtimeout): new keyword 
+       * server-src/conffile.c (dtimeout): ditto
+       * server-src/dumper.c: use dtimeout instead of READ_TIMEOUT
+       * example/amanda.conf.in: document it
+       * man/amanda.8.in: ditto
+       * NEWS: ditto
+
+1998-10-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c (sendbackup_response): a nak error will
+       be a TRY-AGAIN instead of a FAILED.
+
+1998-10-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amlabel.c: move declaration of vtbl_no, datestr
+       and slotcommand to the main function.
+
+1998-10-26  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amlabel.c: remove declaration of pname.
+
+1998-10-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheckdb.sh.in: modify to match new tapelist file
+       format (keyword reuse and no-reuse). Probably no-one use this
+       program.
+
+1998-10-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c (handle_dumper_result): Add sleep time
+       when a dumper failed, it could be a temporary network problem,
+       such as NIS or NFS, better wait a few seconds before retrying.
+
+1998-10-25  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h: remove declaration of argc et argv.
+       * server-src/driverio.h (getresult): add parameters result_argc, 
+       result_argv and max_arg.
+       * server-src/driverio.c (getresult): use new parameters.
+       * server-src/amflush.c (flush_holdingdisk, run_dumps): declare
+       and use result_argc and result_argv instead of global variables
+       argc and argv.
+       * server-src/driver.c (main, handle_taper_result, 
+       handle_dumper_result, dump_to_tape): ditto
+
+1998-10-24  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: do not be quite so accurate in matching
+       the log file lines since messages may be intermixed.  Turn on perl
+       -w switch and make first cut at cleaning up warnings.
+
+1998-10-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h: remove datestamp declaration.
+       * server-src/amcheck.c: remove 'extern' to datestamp declaration.
+       * server-src/amflush.c: declare datestamp.
+       * server-src/amtape.c: remove 'extern' to datestamp declaration.
+       * server-src/driver.c: declare datestamp.
+       * server-src/dumper.c: remove 'extern' to datestamp declaration.
+       * server-src/reporter.c: remove 'extern' to datestamp declaration.
+
+1998-10-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h: remove declaration of tok.
+       * server-src/amflush.c (flush_holdingdisk,run_dumps): declare
+       tok locally.
+       * server-src/driver.c (main, handle_taper_result, handle_dumper_result,
+       dump_to_tape): declare tok locally.
+
+1998-10-23  John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: disable the -E and -h dump estimate checks if $DUMP
+       is not executable.
+
+1998-10-19  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amindexd.c (is_config_valid): fix core dump by moving
+       amfree of conf_dir later in case it is needed in an error message.
+
+1998-10-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c: remove declaration of curlinenum,
+       curlog, curprog and curstr.
+
+1998-10-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amflush.c (main): move declaration of diskqp from
+       global to local.
+
+1998-10-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c (main): move declaration of mailout and 
+       tempfname from global to local.
+
+1998-10-16  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (search_logfile): remove declaration
+
+1998-10-15  Mike Grupenhoff <kashmir@munge.com>
+
+       * server-src/amadmin.c (reuse, no-reuse): don't core dump if tape
+       label not found
+
+1998-10-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/conffile.h: remove declaration of holdingdisks and 
+       num_holdingdisks, declare getconf_holdingdisks().
+       * server-src/conffile.c: define getconf_holdingdisks(),
+       * server-src/holding.c: use getconf_holdingdisks
+       * server-src/find.c: ditto
+       * server-src/amcheck.c: ditto
+       * server-src/amflush.c: ditto
+       * server-src/driver.c ditto
+
+1998-10-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c: remove verbose and force_parameters
+       variables.
+
+1998-10-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/dumper.c: remove declaration of pid.
+       * server-src/dumper.c(do_dump): move declaration of runtime, 
+       dumptime, compresspid, indexpid and killerr from global to local.
+
+1998-10-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c: remove declaration of total_waiting and
+       result_socket.
+       * server-src/planner.c(main): move declaration of initial_size from
+       global to local.
+
+1998-10-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h,server-src/driver.c: move declaration
+       of big_dumpers, degraded_mode and reserved_space from 
+       driverio.h to driver.c
+
+1998-10-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.h (optionstr): remove declaration
+
+1998-10-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * configure.in (SAMBA_CLIENT): fix typo
+
+1998-10-14  John R. Jackson  <jrj@purdue.edu>
+
+       * restore-src/amrestore.c (read_file_header): make a couple of error
+       messages clearer that they refer to problems with a header rather
+       than the image data.
+
+1998-10-13  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/Makefile.am (libamclient_a_SOURCES): missing since
+       clean-up; re-added
+
+1998-10-12  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/INTERNALS (driver and dumper): document <dumpdate> in 
+       FILE-DUMP and PORT-DUMP request, document <chunksize> in 
+       FILE-DUMP request.
+
+1998-10-12  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amtape.c (usage, main, show_device): apply patch from
+       Chris Jones <cjones@clydesdale.math.montana.edu> to support "device"
+       as an option to return the drive device name as reported by the
+       changer.
+       * man/amtape.8: document the new "device" option.
+       * server-src/amverify.sh.in: use the new amtape "device" option to
+       better handle tape changers.  Overhaul for general cleanup and some
+       security issues, plus amverify now tries to support non-tar images.
+       * man/amverify.8.in: document non-tar image issues.
+
+1998-10-08  John R. Jackson  <jrj@purdue.edu>
+
+       * example/amanda.conf.in: fix runspercycle example and comments
+
+1998-10-08  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (SAMBA_CLIENT): try to find it by default; minimal
+       checking
+       * client-src/Makefile.am (WANT_SAMBA): use automake conditionals to
+       enable findpass.o
+       * docs/SAMBA: document that --with-smbclient is no longer required
+       to enable SAMBA support
+       
+       * docs/FAQ: about inconsistencies in active filesystems
+
+1998-10-06  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/DUMPER-API: add `no-record' option to the `backup' command.
+
+1998-10-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/DUMPER-API: subdivise section 3.1.
+
+1998-10-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/DUMPER-API: New `index-<mode>' options.
+       define `support parse-estimate' and `support parse-backup' subcommand.
+       New 'estimate-direct', `estimate-parse', `backup-direct' and
+       `backup-parse' options.
+       Remove PARSE keyword from estimate and backup command.
+
+1998-10-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/DUMPER-API: define PARSE keyword in stderr of the backup
+       command
+
+1998-10-03  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/Makefile.am (EXTRA_DIST): make sure the man-pages that are not 
+       generated by autoconf get into the distribution
+
+1998-10-02  Josef Karthauser  <joe@pavilion.net>
+
+       * changer-src/chg-chio.pl.in (getTapeParams): fix regular expression 
+       for $line; the trailing `s' of slots was missing
+
+1998-10-02  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: fix error message.
+
+1998-10-02  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/taper.c (write_file): fix a problem with tha taper
+       stats where the times were all the same.  The wallclock_str function
+       returns a pointer to a static area so it cannot be called more
+       than once as an argument to a function.
+
+1998-10-01  John R. Jackson  <jrj@purdue.edu>
+
+       * common-src/protocol.c (parse_integer): allow negative numbers.
+
+1998-10-01  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: add timestamps.
+
+1998-10-01  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/DUMPER-API: define `support index', to be used instead of the
+       previous `index-*' sub-commands
+
+1998-09-30  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/Makefile.am (libexec_PROGRAMS, sbin_SCRIPTS): don't use 
+       backslashes for continuation; this seems to break automake :-(
+
+1998-09-30  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amanda.8.in: minor typo in "reserve" description.
+
+1998-09-29  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/taper.c (end_tape): do not rewind the tape when done.
+
+1998-09-29  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (WANT_CLIENT, WANT_RESTORE, WANT_SERVER, 
+       WANT_RECOVER, WANT_TAPE, WANT_AMPLOT, WANT_CHG_SCSI): automake
+       conditionals
+       * amplot/Makefile.am: use them
+       * changer-src/Makefile.am: ditto
+       * client-src/Makefile.am: ditto
+       * common-src/Makefile.am: ditto
+       * man/Makefile.am: ditto
+       * recover-src/Makefile.am: ditto
+       * restore-src/Makefile.am: ditto
+       * server-src/Makefile.am: ditto
+       * tape-src/Makefile.am: ditto
+
+       * Makefile.am: don't print commands that work around old aclocal bug
+
+       * docs/DUMPER-API: remove environment variables, and mention a
+       program that will help translating disklist entries to device names, 
+       mount points and filesystem types
+
+       * recover-src/extract_list.c (extract_files_child): do not crash
+       after failing to read the dump file header
+       Reported by Jose Cheng <jcheng@math.ist.utl.pt>
+
+1998-09-28  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/taper.c (taperscan_slot): initialize scan_datestamp, to
+       avoid amfree of uninitialized pointer
+       Reported by Lance A. Brown <brown9@niehs.nih.gov>
+
+1998-09-27  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/DUMPER-API (USER, GROUP): detailed security mechanisms
+       (estimate, estimate-parse): can print `KILL' after the estimate
+       
+       * docs/DUMPER-API: various suggestions from Eric Siegerman
+       <erics@now.com> and some explanations added
+       
+1998-09-27  Andy Farkas  <andyf@speednet.com.au>
+
+       * man/amlabel.8.in (labelstr): fix typo
+
+1998-09-26  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * recover-src/extract_list.c (extract_files_child): fix-up
+       no_initial_params if password or domain information is not found
+       Reported by Jose Cheng <jcheng@math.ist.utl.pt>
+
+       * docs/DUMPER-API: extended `index' to `index-from-output' or
+       `index-from-image', as suggested by Dale Hagglund <rdh@best.com>.
+       Explained that the dumptype option `program' is the name of the
+       wrapper program
+
+1998-09-25  John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: fix --with-dump-honor-nodump test.  Patch by
+       Jonas Oberg <jonas@coyote.org>.
+
+1998-09-24  John R. Jackson  <jrj@purdue.edu>
+
+       * example/disklist: document the "spindle" and "interface" fields.
+       Reported by Brendan M Coffey <bcoffey@connix.com>.
+
+1998-09-24  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/DUMPER-API: added draft description of the DUMPER API
+       * Makefile.am (EXTRA_DIST): add it to the distribution
+
+       * config/acinclude.m4 (AC_VALIDATE_CACHE_SYSTEM_TYPE): make sure
+       cached values for host, build and target system types match with the
+       guessed ones
+       * configure.in: use it
+
+1998-09-23  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in: sort the host and partition names.
+       From David Wolfskill <dhw@whistle.com>.
+
+1998-09-23  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/taper.c (getcmd): typo in last DEBUGging patch
+
+1998-09-22  Tim Perkins  <Tim.Perkins@ddg.phar.cam.ac.uk>,  Alexandre Oliva <oliva@dcc.unicamp.br>
+
+       * client-src/selfcheck.c (check_disk): fix VDUMP auto-detection
+
+1998-09-22  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * changer-src/chg-mtx.sh.in: replace rew with rewind
+       * changer-src/chg-zd-mtx.sh.in: ditto
+       Reported by Henning Holtschneider <hh@loca.net>
+
+       * client-src/sendsize.c: remove usage of #error
+       Reported by Jay Orr <orr@vss.fsi.com>
+
+1998-09-21  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amanda.8.in: document the new "tapebufs" parameter.
+
+1998-09-21  Kelly Setzer  <setzer@telalink.net>
+
+       * server-src/taper.c (NBUFS): replaced with conf_tapebufs
+       (THRESHOLD): now means `empty bufs' instead of `full bufs'
+       * server-src/conffile.c: add support for the "tapebufs" option
+       * server-src/planner.c: ditto
+       * examples/amanda.conf.in: add sample "tapebufs" entry
+
+       * server-src/amlabel.c (main): adds entry to tapelist with date
+       19700101
+
+1998-09-20  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/taper.c (getcmd): print DEBUGging output to stderr
+       Reported by Henning Holtschneider <hh@loca.net>
+
+1998-09-19  Eric Doutreleau <Eric.doutreleau@int-evry.fr>
+
+       * server-src/driverio.h (MAX_DUMPERS): increased from 15 to 63 in
+       order to launch more dumper in parallel
+       * example/amanda.conf.in (inparallel): Add the fact that it is
+       limited by MAX_DUMPERS
+
+1998-09-18  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * common-src/Makefile.am (libamanda_la_LDFLAGS): use libtool
+       -release instead of -version_info, so as to encode the Amanda
+       release number in the library name.  Problems related with
+       pre-installed libraries should disappear, and separate releases can
+       now be installed into the same directory without the risk of one
+       using libraries from the other.
+
+1998-09-18  Michael C. Povel  <Michael.Povel@hub.de>
+
+       * changer-src/chg-scsi.c (wait_ready): new function; keeps retrying
+       until success or timeout
+       (ask_clean, main): use it
+
+1998-09-18  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/selfcheck.c (check_options): don't require runtar for
+       SAMBA backups
+       
+       * client-src/rundump.c: fix support for VDUMP-only installation
+       * client-src/selfcheck.c (check_options): fix detection of advfs
+       * client-src/sendsize.c (getsize_dump): ditto
+       * client-src/sendbackup-dump.c (start_backup): ditto
+       Reported by Tim Perkins <Tim.Perkins@ddg.phar.cam.ac.uk>
+
+1998-09-16  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amadmin.8.in: document that "hostname" is optional for "info".
+       Reported by David Wolfskill <dhw@whistle.com>.
+
+1998-09-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ: common compile-time and link-time errors
+
+1998-09-11  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/tapefile.c (lookup_last_reusable_tape): use new
+       calling sequence that passes how old a tape to return.  Remove
+       lookup_previous_reusable_tape().
+       * server-src/tapefile.h (lookup_last_reusable_tape): use new
+       calling sequence that passes how old a tape to return.  Remove
+       lookup_previous_reusable_tape().
+       * server-src/amadmin.c (tape): use new lookup_last_reusable_tape
+       calling sequence.
+       * server-src/amcheck.c (taper_scan, start_server_check): use new
+       lookup_last_reusable_tape calling sequence.
+       * server-src/amflush.c (confirm): use new lookup_last_reusable_tape
+       calling sequence.
+       * server-src/amtape.c (taper_scan): use new lookup_last_reusable_tape
+       calling sequence.
+       * server-src/reporter.c (output_tapeinfo): use new
+       lookup_last_reusable_tape calling sequence.
+       * server-src/taper.c (taper_scan): use new lookup_last_reusable_tape
+       calling sequence.
+
+1998-09-11  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendbackup-gnutar.c (re_table): ignore
+       `load_client_codepage' message from SAMBA
+
+1998-09-11  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amstatus.pl.in (all): fix USE_VERSION_SUFFIXES=yes
+       problems.  Reported by David Eckelkamp <davide@locutus.tradewave.com>.
+
+       * man/amstatus.8.in (all): fix minor typos.
+
+1998-09-10  John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in (LFS): add code that might support configuring large
+       files on HP-UX.
+
+1998-09-10  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/conffile.c (dump_configuration): runspercycle is not a
+       member of dumptype_t
+       (init_holdingdisk_defaults): init chunksize with documented default,
+       not -1, because it wouldn't be recalculated
+
+       * docs/INSTALL: URL for SAMBA was broken; note about 1.9.18p10 bug
+
+1998-09-10  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * docs/SAMBA: 1.9.18p10 has a bug
+
+1998-09-09  Terje Malmedal  <tm@funcom.com>
+
+       * common-src/stream.c (stream_server, stream_client): added
+       SO_KEEPALIVE option so we get an error if the other side crashes
+
+1998-09-09  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (CHIO): look for chio and AC_SUBST it
+       (MT, CHS): if not found, use just the program name
+       
+1998-09-09  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (last_level): return the last level
+       even it is still on holding disk if reserve < 100.
+
+1998-09-09  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/reporter.c (divzero, divzero_wide): print `#'s on
+       overflow
+
+       * server-src/amtape.c (show_init): no longer print `scanning'
+       message
+       (show_init_show, current_init_all): call show_init, then print the
+       appropriate `scanning' message
+       Reported by David Wolfskill <dhw@whistle.com>
+
+       * changer-src/chg-scsi.c (main): use new multi-configuration
+       mechanism only if tape_device contains only a single digit
+
+1998-09-08  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/planner.c (setup_estimate): Don't write a
+       "mismatch: no tapelist record, but curinfo next_level0" message
+       and force a level 0 when reserve < 100.
+
+1998-09-08  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/holding.h (get_amanda_names): return a filetype_t
+       instead of an int.
+       * server-src/holding.c (get_amanda_names): return the filetype_t
+       of the file or F_UNKNOWN if it's not an amanda file.
+       * server-src/find.c (search_holding_disk): Use the new return 
+       type of get_amanda_names.
+       * server-src/amflush.c (flush_holdingdisk): Don't write a
+       "ignoring cruft file" message for chunk files,
+       filetype is F_CONT_DUMPFILE.
+
+1998-09-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (extract_files_child): don't write
+       the samba password to the debug file.
+
+1998-09-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driverio.c (update_info_dumper): set inf.command to
+       NO_COMMAND if reserve< 100 because if you force a level 0 with
+       'amadmin force', it will do level 0 every days until you flush them
+       to tape.
+
+1998-09-03  Matthias Urlichs    <smurf@noris.net>
+
+       * recover-src/uscan.l: recognize "?" as alias for "help"
+
+       * configure.in (MAILER): recognize "mail" as well as "Mail" and
+       "mailx"
+
+       * client-src/calcsize.c (add_file_dump, add_file_unknown): only get
+       sizes of directories and files
+
+       * client-src/amandates.c (start_amandates): create amandates if
+       error is either EINTR or ENOENT
+
+       * common-src/dgram.c (dgram_send_addr): handle ECONNREFUSED by not
+       dying when receiving, and retrying when sending, a packet.  The
+       server may get this error when a client reboots and hasn't started
+       inetd yet.
+       * common-src/protocol.c (handle_incoming_packet): ditto
+
+       * server-src/driver.c (read_schedule): catch cases when the time
+       goes negative.  Some operators have the bad habit of syncing clocks
+       late at night. ;-)
+
+       * common-src/dgram.h (MAX_DGRAM): increased to 64Kb
+       * NEWS: ditto
+       * client-src/amandad.c (main): read the pipe from the child
+       incrementally: the pipe buffer of many OSes is shorter than
+       MAX_DGRAM.  Instead of SIGCHLD, note end-of-data by way of
+       end-of-file
+       (sigchild_jump, sigchild_flag): removed
+       * client-src/sendbackup.c (main): instead of fork-and-exit, tell
+       amandad to process our data by closing our end of the pipe
+       
+1998-09-03  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * NEWS: another typo (too late :-(
+
+1998-09-03  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/driver.c: amanda will not use an holding disk
+       if the directory with the datestamp already exist.
+
+1998-09-03  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * Amanda 2.4.1 released
+       
+1998-08-27  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * NEWS: typo
+
+1998-08-27  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/INSTALL: update some version numbers; SAMBA 1.9.18p10 has
+       fixed the bug in p8; using p8 is not recommended any more
+       * docs/SAMBA: ditto
+
+       * config/config.guess: updated to libtool 1.2b's, in order to
+       auto-detect some recent architectures
+       * config/config.sub: ditto
+
+       * server-src/amcleanup.sh.in (sbindir): amreport now lives in
+       sbindir; added it to PATH and removed full pathnames to binaries
+
+1998-08-27  Blair Zajac  <blair@gps.caltech.edu>
+
+       * configure.in: Add the directory /usr/lib/fs/vxfs to the search
+       path where configure looks for vxdump and vxrestore.  This is for
+       Solaris so it can automatically handle vxfs filesystems.
+       * client-src/sendbackup-dump.c: add missing last NULL argument to
+       newvstralloc().
+       * server-src/dumper.c: add missing last NULL argument to
+       newvstralloc().
+       * NEWS: reorder 2.4.1 items into most to least important for most
+       users.
+       * config/acconfig.h: update comment for VXDUMP and VXRESTORE to
+       include systems where the Veritas filesystem is used.
+
+1998-08-21  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/amanda.8.in (nofull): only level 1 incrementals
+
+1998-08-20  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * changer-src/chg-mtx.sh.in (PATH): added /usr/local/bin
+
+       * configure.in (BUILD_CHANGER_SCRIPTS_LIBEXEC): added chg-zd-mtx
+       (AC_OUTPUT): ditto
+       * changer-src/Makefile.am (EXTRA_SCRIPTS): ditto
+       * docs/TAPE.CHANGERS (chg-zd-mtx): documented it
+       (chg-mtx): mentioned chg-zd-mtx
+
+1998-08-20  Eric Doutreleau  <Eric.Doutreleau@int-evry.fr>
+
+       * changer-src/chg-zd-mtx.sh.in: new changer script for
+       Zubkoff/Dandelion version of mtx.
+
+1998-08-19  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SAMBA: updated; documented new patch (sambatar.diff,
+       available in the patches page) and requirements about backup user.
+       * docs/INSTALL: documented new patch
+
+1998-08-18  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c (regex_s): refuse to compile if SAMBA_CLIENT
+       and HAVE_DUMP_ESTIMATE are both defined: the regexp that matches the
+       estimate from DU 4.0's dump also matches an output line from
+       smbclient, that provides an incorrect estimate.
+       * docs/SYSTEM.NOTES: document the problem
+
+1998-08-14  John R. Jackson  <jrj@purdue.edu>
+
+       * docs/TAPE.CHANGERS: describe "advance" and clean up some spelling.
+
+1998-08-13  Alexandre Oliva  <oliva@dcc.unicamp.br>, Marcel Hild  <hild@id-pro.de>
+
+       * configure.in (--with-portrange): validate and define PORTRANGE
+       * example/config.site: document it
+       * config/acconfig.h (PORTRANGE): prepare for configure define
+       * common-src/stream.c (stream_server): use PORTRANGE to limit TCP
+       unreserved server sockets
+
+1998-08-12  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ: working around `dumps way too big'
+
+1998-08-11  Alexandre Oliva  <oliva@dcc.unicamp.br>, Gunnar Gunnarsson  <gunnar@ki.ericsson.se>
+
+       * common-src/token.h (rxquote, shquote): new functions
+       * common-src/token.c (rxquote) quotes a string into an equivalent
+       regular expression
+       (shquote): quotes all shell special meta-characters, so that a
+       string can be safely passed down for shell interpretation in
+       system() or popen()-like calls
+       * server-src/amindexd.c (build_disk_table): quote the disk_name with 
+       both rxquote and shquote
+
+1998-08-11  John R. Jackson  <jrj@purdue.edu>
+
+       * changer-src/chg-manual.sh.in: put the debug file in DEBUG_DIR for
+       security.  Clean up and enhance logging.  Fix locations of the
+       changer files.  Source the changerfile into the script so it can
+       override the request() function and allow alternatives to /dev/tty
+       (e.g. E-mail, syslog).  Issue rewind before status (Solaris does
+       not give a good status report right after a tape is loaded).
+
+1998-08-10  Nick Hibma  <nick.hibma@jrc.it>
+
+       * changer-src/chg-chio.pl.in: move to first slot if last is unused
+
+1998-08-07  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * example/Makefile.am (EXTRA_DIST): add DIN-A4.ps
+
+1998-08-07  Günter Felkel  <G.Felkel@edelmann.de>
+
+       * example/DIN-A4.ps: new file
+
+1998-08-06  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * tape-src/tapetype.c (initrandombytes): use random() instead of
+       rand(), its low-order bits are more random
+       (main): call srandom(seed) instead of srand(seed)
+       (USE_RAND): if defined, reverts to using rand() and srand(seed)
+
+       * docs/FAQ: some notes about driving real tape changers
+
+1998-08-05  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/amreport.8.in (SYNOPSIS): replace `amtoc' with `amreport'
+
+1998-08-04  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c: revert 1998-08-01's change, it wouldn't
+       even compile, as amfree() expands to a statement, not an expression, 
+       so it cannot be used as the `increment' part of a for loop.
+
+       * server-src/planner.c (main): if runs_per_cycle is set to zero or
+       negative, set it to 1, in order to avoid division by zero.
+       * server-src/amadmin.c (balance): ditto
+
+1998-08-01  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c: replace free(line) with amfree(line),
+       because line is not ensured to be non-NULL
+       
+       * docs/FAQ: amandad: error receiving message
+       
+       * docs/FAQ: difference between skip-full and strategy nofull
+
+1998-07-31  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ: software or hardware compression?
+
+       * server-src/driver.c (adjust_diskspace): do not abort just because
+       a holding disk file is missing
+       (main): report warning if holding disk directory could not be
+       created, and do not use it
+       Reported by Albrecht Gebhardt <agebhard@zidsrv.sci.uni-klu.ac.at>
+
+       * example/Makefile.am (EXTRA_DIST): add 8.5x11.ps to the
+       distribution
+       Reported by Jason L Tibbitts III <tibbs@hpc.uh.edu>
+
+       * server-src/conffile.c (get_holdingdisk): define chunksize 0 as
+       INT_MAX/1024, and chunksize -1 as -INT_MAX/1024
+       * server-src/driver.c (find_diskspace): accept negative chunksizes
+       as the maximum size (in modulus) for using the holding disk
+       * man/amanda.8.in (chunksize): document the usage of negative
+       values, and improve the explanation of chunking
+       * example/amanda.conf.in: ditto
+
+1998-07-29  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ: disk offline
+
+1998-07-27  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * restore-src/amidxtaped.c (main): use tape_rewind() instead of
+       running `mt'
+
+       * server-src/amcleanup.sh.in (reporter): update to call amreport.
+       (amdump.<n>) update to use the same renaming technique introduced in
+       June 30's change to amdump.
+
+1998-07-25  Michael Graff  <explorer@vix.com>
+
+       * changer-src/Makefile.am (install-exec-hook): support $(DESTDIR)
+       * client-src/Makefile.am (install-exec-hook): ditto
+       * man/Makefile.am (install-data-hook): ditto
+       * recover-src/Makefile.am (install-exec-hook): ditto
+       * restore-src/Makefile.am (install-exec-hook): ditto
+       * server-src/Makefile.am (install-exec-hook): ditto
+
+       * configure.in: link krb5 and com_err in for Kerberos support, if
+       they exist
+
+1998-07-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/reporter.c (copy_template_file): add braces to 
+       remove warning
+       * tape-src/tapeio.h: declare is_zftape to remove warning in
+       amlabel.c and taper.c
+
+1998-07-23  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/driver.c (any_delayed_disk): new variable, to ensure
+       that we do not leave the main driver loop if there are delayed disks 
+       but there are no active dumpers
+       (main): instead of checking whether idle_reason is IDLE_START_WAIT,
+       check whether there is any_delayed_disk for remaining in the loop
+       (start_degraded_mode): set any_delayed_disk when needed
+       Reported by Peter Walker <peter@talarian.com>
+
+1998-07-23  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/reporter.c (main): handle LPRCMD being undefined.
+
+1998-07-23  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * client-src/selfcheck.c (check_suid): new function to check if a
+       program is SUID root.
+       * client-src/selfcheck.c (check_overall): check that runtar and
+       rundump are SUID root.
+
+1998-07-22  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in: version number set to 2.4.1
+
+       * recover-src/Makefile.am (LDADD): libamtape imports symbols from
+       libamanda, so it must be listed first
+
+       * changer-src/Makefile.am (LDADD): remove duplication of libamserver
+       and libamanda, as they no longer provide symbols for each other
+       * server-src/Makefile.am (LDADD): ditto
+       
+1998-07-21  Blair Zajac  <blair@gps.caltech.edu>
+
+       * server-src/amrmtape.sh.in: now use amanda.conf's tapelist variable
+       * server-src/amcheckdb.sh.in:  now use amanda.conf's tapelist variable
+       * server-src/amfreetapes.sh.in: now use amanda.conf's tapelist variable
+       * server-src/amtoc.pl.in: now use amanda.conf's tapelist variable,
+       make perl4 compatible
+
+1998-07-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ (results missing): suggestions to work around the UDP
+       packet size limit
+
+1998-07-16  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ (amrecover): a config name may have to be specified
+       Reported by digital messiah <dmessiah@silcon.com>
+
+1998-07-15  Blair Zajac  <blair@gps.caltech.edu>
+
+       * server-src/reporter.c (main): declare optind
+
+1998-07-15  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in: created Amanda 2.4.1 branch
+
+       * example/amanda.conf.in: strategy noinc is not implemented yet
+
+1998-07-14  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * NEWS: new runspercycle keyword
+       * server-src/conffile.h: new runspercycle keyword
+       * server-src/conffile.c: new runspercycle keyword
+       * server-src/amadmin.c (balance): new runspercycle keyword
+       * server-src/planner.c (main): new runspercycle keyword
+       * man/amanda.8.in: document new runspercycle keyword
+       * example/amanda.conf.in: example for new runspercycle keyword
+
+1998-07-13  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ: What to do if DUMP program is not available.
+       * client-src/selfcheck.c (check_overall): if a needed program is
+       missing, print an error message.
+       Reported by Klaus Hoffmann <handatalog@csi.com>
+
+       * */Makefile.am: checked library version numbers, no need for update
+       
+       * configure.in: version number set to 2.4.1b1
+
+1998-07-11  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/FAQ: new entries: how to label tapes, (not) spanning large
+       filesystems across tapes, how to enable index generation,
+       overwriting selected tapes, cleaning up databases, selecting tape
+       changer.
+       
+1998-07-10  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/Makefile.am (EXTRA_DIST): amreport.8 is built from .8.in
+
+       * configure.in (AC_OUTPUT): generate chg-chio.pl
+       * changer-src/Makefile.am (EXTRA_DIST): removed chg-chio.c
+       * changer-src/chg-chio.c: removed, as it was confusing make
+       
+1998-07-10  Nick Hibma  <nick.hibma@jrc.it>, Alexandre Oliva <oliva@dcc.unicamp.br>
+
+       * changer-src/chg-chio.pl.in: new script, created to replace old
+       chg-chio written in C
+       * docs/TAPE.CHANGERS (chg-chio): document it
+       * changer-src/Makefile.am (EXTRA_SCRIPTS): add chg-chio
+       (EXTRA_DIST): still include chg-chio.c, just in case it is useful
+       * configure.in (BUILD_CHANGER_SCRIPTS_LIBEXEC): add chg-chio
+       
+1998-07-08  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/reporter.c (main): if no arguments are given, preserve
+       original behavior; require config name otherwise.  Perform better
+       argument checking.
+       * example/DLT.ps (DrawHost): discard additional argument introduced
+       in Steven Freed's modification
+       * example/EXB-8500.ps (DrawHost): ditto
+       * example/HP-DAT.ps (DrawHost): ditto
+
+       * server-src/Makefile.am (amreport_SOURCES): build from reporter.c
+       (driver_SOURCES) removed, no longer needed
+       * man/Makefile.am (EXTRA_DIST): added amreport.8
+
+1998-07-08  Steven Freed  <sfreed@gilasoft.com>
+
+       * server-src/reporter.c (usage): new function
+       (main): accept command-line arguments for selecting config name,
+       output file, log file name to read from, postscript file to write
+       to.
+       (output_summary): print tape labels list, tape section numbers and
+       dump sizes.
+       * server-src/amdump.sh.in: run amreport
+       * server-src/amflush.c (main): ditto
+       (run_dumps): ditto
+       * configure.in (BUILD_SERVER_PROGS_SBIN): add amreport
+       (BUILD_SERVER_PROGS_LIBEXEC): remove reporter
+       * man/amreport.8.in: new file
+       * man/Makefile.am (man_MANS): added amreport.8
+       * example/8.5x11.ps: new file
+
+1998-07-08  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * Makefile.am (ACLOCAL_M4): fix ||/&& precedence problem
+
+1998-07-07  John R. Jackson  <jrj@purdue.edu>
+
+       * changer-src/scsi-chio.c: move #include's so this will compile on
+       systems without <sys/mtio.h> (e.g. AIX).
+
+1998-07-06  John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/sendsize.c (handle_dumpline): allow the dump block
+       count estimate to be negative.  Found by Lance A. Brown
+       <brown9@niehs.nih.gov> on NeXT.
+
+       * common-src/Makefile.am, common-src/security.c: add TEST code to
+       security.c so people can do "make security" and have a test program
+       to track down why they are getting "access as XXX not allowed from
+       YYY@ZZZ".
+
+       * common-src/security.c (bsd_security_ok): allow the remote user
+       field in .amandahosts to be empty ala .rhosts.
+
+1998-07-04  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amcheck.c (start_server_check): report space use for
+       holding disk if a negative value is given in the use parameter.
+
+       * server-src/driver.c (main): compute holding disk space if 
+       a negative value is given in the use parameter..
+
+       * man/amanda.8.in (use) : document negative use paramater for 
+       holding disk.
+
+       * example/amanda.conf.in (use): document negative use paramater for
+       holding disk..
+
+1998-07-04  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * man/amanda.8.in (reserve): document it
+       * example/amanda.conf.in (reserve, gigabytes): ditto
+       (etimeout) negative number stands for total estimate time
+
+       * NEWS: documented major changes since amanda 2.3.0.4
+
+       * docs/INSTALL: refer to patch-system for editing services and
+       inetd.conf
+
+       * docs/FAQ: added entries for common amdump and amcheck errors
+
+       * COPYRIGHT: updated to 1998, refer to Amanda Development Team
+       * AUTHORS: who is the Amanda Development Team
+
+1998-07-03  John R. Jackson  <jrj@purdue.edu>
+
+       * docs/SYSTEM.NOTES: add comment about using the variable device name
+       on IRIX.  Otherwise, IRIX will write 4KByte physical blocks, which
+       it appears to read OK, but not if you take the tape to some other
+       system that does what you tell it.  Discovered by Steve E. Khoo
+       (steve@gordian.com).
+
+1998-07-02  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/planner.c (setup_estimate): handle new disks with
+       skip-full correctly.
+
+       * Makefile.am (aclocal.m4): must depend on libtool.m4, so as to
+       force it to be newer on distributions.
+
+1998-07-01  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/driverio.h: change reserved_space to unsigned long to
+       match free_space() and avoid a compiler warning.
+
+1998-06-30  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amanda.8.in: fix amrecover synopsis and add a short description.
+       Noted by Brendan M Coffey <bcoffey@connix.com>.
+
+       * example/amanda.conf.in: make tapecycle example fit dumpcycle value
+       better.  Noted by Tom.Croll@radisys.com and suggested comments from
+       Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+1998-06-30  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * server-src/amdump.sh.in (maxdays): set up with tapecycle+2
+       (days): loops from 1 to $maxdays, but stops if amdump.$days does not 
+       exist, so that we only rename amdump log files that exist.  This
+       prevents too long loops in case of an infinite tapecycle.
+       Reported by Nick Hibma <nick.hibma@jrc.it>
+
+1998-06-28  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * common-src/security.c (bsd_security_ok): accept case mismatches
+       when comparing hostnames and usernames from amandahosts, and assume
+       localuser if username is missing.
+       * docs/INSTALL: clarify BSD security and amandahosts, WRT to
+       non-FQDNs.
+       Reported by Chris Shenton <chris@absinthe.shenton.org>
+
+       * server-src/reporter.c (output_tapeinfo): degraded mode no longer
+       implies incremental dumps only.
+       Reported by Randy Dees <rrd@amherst.com>
+
+1998-06-26  John R. Jackson  <jrj@purdue.edu>
+
+       * configure.in: fix BSD/OS Kerberos include file location.
+
+1998-06-26  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * config/ltmain.sh: install official patch to libtool 1.2a
+
+       * configure.in: do not set max file size for Solaris 2.6, it is no
+       longer used.
+
+1998-06-26  Tim McNerney  <mumbly@netcom.com>
+
+       * common-src/fileheader.c (parse_file_header): accept missing
+       PROGRAM in tape section header, for backward compatibility.
+
+1998-06-25  Blair Zajac  <blair@gps.caltech.edu>
+
+       * server-src/amflush.c: fix mismatch arguments to error()
+
+1998-06-24  Steven Freed  <sfreed@gilasoft.com>
+
+       * configure.in (dump-honor-nodump): fix test for `-h' support
+
+1998-06-24  Scott Mesches  <mesches@allison.Colorado.EDU>
+
+       * example/DLT.ps: new file
+       * example/Makefile.am (EXTRA_DIST): add DLT.ps
+
+1998-06-24  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * Makefile.am (EXTRA_DIST): moved CHANGES into ChangeLog
+
+       * recover-src/extract_list.c (extract_files_child): handle
+       IS_UNKNOWN dumptype as IS_DUMP
+
+       * client-src/sendsize.c (getsize_dump): always create pipe for
+       killpgrp.
+
+       * client-src/amandad.c (sendnak): report `UNKNOWN' error if str is
+       NULL.
+
+       * amplot/amplot.awk: ignore `interface-state'
+       Reported by Peter Walker <peter.walker@talarian.com>
+
+1998-06-24 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+       * server-src/amrmtape.sh.in: enable verbose by default; implement -q 
+       for quiet.
+       * man/amrmtape.8.in: ditto
+       Suggested by Nick Hibma  <nick.hibma@jrc.it>
+       
+1998-06-24  Nick Hibma  <nick.hibma@jrc.it>
+
+       * server-src/amrmtape.sh.in: better error reporting for incorrect
+       database entries
+
+1998-06-24  Dan Swartzendruber <dswartz@druber.com>
+       
+       * server-src/conffile.h (RESERVE): new keyword.
+       * server-src/conffile.c (RESERVE): ditto.
+       (getconf_seen): recognize "reserve" keyword.
+       (getconf_int): return value of "reserve" keyword.
+       (read_confline): parse "reserve" line.
+       * server-src/driverio.h (reserved_space): new global
+       * server-src/driver.c (main): compute holding disk space to reserve
+       for degraded dumps.
+       (start_degraded_mode): if we haven't hit degraded mode reservation
+       limit, allow full dump.
+       
+1998-06-18  Blair Zajac <blair@gps.caltech.edu>
+
+       * config/ltconfig: update to 1.2a
+       * config/ltmain.sh: update to 1.2a
+       * config/libtool/libtool.m4: update to 1.2a
+
+1998-06-17  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/dumper.c (write_tapeheader): comment out some variables
+       to get rid of a compiler warning.
+
+1998-06-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (bumpsize): write wrong equation for bump
+       threshold.
+
+1998-06-15  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * man/amanda.8.in: add info about the chunksize parameter
+       of the holdingdisk.
+       * man/amanda.8.in: add info about amstatus command
+
+1998-06-13  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * common-src/Makefile.am (libamanda_version): updated
+       * tape-src/Makefile.am (libtape_version): updated
+       * client-src/Makefile.am (libclient_version): updated
+       * server-src/Makefile.am (libserver_version): updated
+
+       * server-src/taper.c (read_file): if switching to the next file
+       fails or there's no next file, do not send a `W' to taper writer.
+
+       * server-src/changer.h (changer_clean): new function
+       * server-src/changer.c (changer_clean): ditto
+
+1998-06-13  Michael C. Povel  <mcp@ladyada.han.de>
+
+       * changer-src/chg-scsi.c: added ejetct_tape and sleep for external
+       tape devices, and changed some code to allow multiple drives to use
+       their own slots. Also added support for reserverd slots.
+       * changer-src/libscsi.h (get_clean_state, eject_tape): new functions 
+       * changer-src/scsi-chio.c (get_clean_state, eject_tape): implemented 
+       using Linux ioctls
+       * changer-src/scsi-hpux.c (get_clean_state, eject_tape): do nothing, 
+       until someone implements them
+       * changer-src/scsi-proto.c (get_clean_state, eject_tape): new
+       functions
+       * docs/TAPE.CHANGERS: document new configuration file format
+       * example/chg-scsi.conf: sample configuration file
+       * example/Makefile.am: add chg-scsi.conf to the distribution
+       * server-src/amtape.c: add support for `clean' command
+
+1998-06-13  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SYSTEM.NOTES: clean-up
+
+       * docs/FAQ: new file
+       * docs/SUNOS4.BUG: removed
+       * Makefile.am: remove docs/SUNOS4.BUG and add docs/FAQ
+       
+       * example/amanda.conf.in (bumpmult): fixed equation for threshold
+       * man/amanda.8.in (bumpsize): fix threshold example.
+       problem reported by Brian McEntire <brianm@fsg1.nws.noaa.gov>
+
+       * server-src/logfile.c (open_log): open log file with mode 0600.
+
+       * server-src/amdump.sh.in: refuse to run if either amdump or log
+       exist in logdir.
+       * server-src/amflush.c (main): refuse to run if log exists.
+       * server-src/amcheck.c (start_server_check): do not perform tape
+       testing if amdump and/or log exist in logdir.
+
+1998-06-11  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * restore-src/amrestore.c (restore): fixed -p flag (and amrecover)
+       should not dup2( A, B ); aclose(A) when A == B
+
+1998-06-10  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c (getsize_dump): use killpgrp
+       unconditionally, so we're not bitten by setuid dump programs.
+       * client-src/killpgrp.c: enable unconditionally.
+
+       * tape-src/tapetype.c: new program: calculates tapetype parameters.
+       * tape-src/Makefile.am (EXTRA_PROGRAMS): added tapetype.
+       * example/amanda.conf.in: point to tapetype program.
+
+1998-06-09  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SAMBA: added notes about (not) backing up registry files and
+       ACLs with SAMBA.
+       * docs/INSTALL: point to docs/SAMBA for usage and limitations
+
+1998-06-08  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (amanda_cv_print_command): removed; using PRINT
+       instead.
+
+1998-06-07  Todd Kover <kovert@omniscient.com>
+
+       * add --with-owner option to allow installed binaries to be owned
+       by someone other than the amanda user
+
+       * add GB as valid holding disk size.
+
+1998-06-07  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * server-src/amadmin.c (info): don't need to specify an host.
+
+       * server-src/amadmin.c (due): new due command to write when a
+       filesystem is due ffor next level 0 or how much days it is
+       overdue.
+
+       * server-src/amstatus.pl.in (dump_size): new function to report
+       the size of a dump split on multiple files.
+
+1998-06-05  Jean-Louis Martineau <martineau@IRO.UMontreal.CA>
+
+       * recover-src/extract_list.c (read_buffer): write a message
+       when amrecover timeout waiting for amrestore to send the dump.
+
+1998-06-04  John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/getfsent.c (main): use a dynamically allocated string
+       for the lookups since dev2rdev alters it on the fly and some systems
+       drop core for trying to write into read only memory.  Also add the
+       capability of passing additional lookups on the command line.
+
+       * common-src/Makefile.am, common-src/file.c (main),
+       common-src/token.c (main), server-src/conffile.c (dump_configuration,
+       main), server-src/diskfile.c (main), server-src/infofile.c (main):
+       Clean up compiler warnings in the test programs and make them all
+       work again.
+
+1998-06-03  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * amplot/amplot.sh.in: modified command line argument parsing
+       mechanism, so as to prevent shell quoting problems and unportable
+       constructs.
+       Reported by Chris Jones <cjones@clydesdale.math.montana.edu>
+
+1998-06-02  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amcheck.c (main), server-src/reporter.c (main): make
+       sure internal errors, such as the mail command failing, get
+       reported.  In the case of amcheck, they go to stderr even if -m is
+       set since there didn't seem to be anyplace better to do so and if
+       this is running from a cron job it might get back to a real user.
+       For reporter, the errors go to .../amdump along with everything
+       else from the amdump script, and they should also go to .../log,
+       except since it's reporter that's having the trouble, they probably
+       will not make it into the mail report.
+
+1998-06-01  John R. Jackson  <jrj@purdue.edu>
+
+       * client-src/killpgrp.c: clean up minor compiler warnings by not
+       building term_kill_{soft,hard} unless they are needed.
+
+       * server-src/driverio.c (dumper_cmd): clean up compiler warning
+       in printf format by forcing argument to always be long and using %ld.
+
+       * server-src/driver.c: include <holding.h> to get declaration for
+       unlink_holding_files and avoid a compiler warning.
+
+       * common-src/amanda.h, common-src/match.c (validate_glob, match_glob,
+       glob_to_regex), recover-src/amrecover.h, recover-src/extract_list.c
+       (add_glob, add_regex, add_file, delete_glob, delete_regex,
+       delete_file), recover-src/help.c (help_list), recover-src/uparse.y,
+       recover-src/uscan.l, man/amrecover.8.in: add shell wildcard support
+       for the add/delete amrecover commands.  Add addx/deletex commands
+       that use regular expressions.  Support more characters in path names.
+
+1998-06-01  Dan Swartzendruber  <dswartz@druber.com> via John R. Jackson
+
+       * server-src/amlabel.c (main): check argc before referencing too
+       far into argv for "-f".
+
+1998-06-01  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SYSTEM.NOTES: advise Linux users to use dump without
+       setuid/setgid
+
+       * docs/INDEXING: update dumptype syntax
+
+1998-05-29  John R. Jackson  <jrj@purdue.edu>
+
+       * server-src/amindexd.c (uncompress_file, process_ls_dump,
+       build_disk_table, is_dir_valid_opaque, opaque_ls): fix file
+       descriptor leak, log the amadmin find command, fix error reporting
+       from routines that do not generate system errors.
+       * common-src/amanda.h: make sure errno is saved through amfree().
+
+1998-05-28  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * docs/SYSTEM.NOTES: GNU tar must be patched on HP/UX.
+       * patches/tar-1.12.patch: ditto.
+
+       * server-src/taper.c (endtape): do not log amount of used tape after 
+       entering degraded mode.
+
+       * client-src/sendsize.c (getsize_dump): pass at least argv[0] to
+       killpgrp.
+
+1998-05-28  Paul R. Johnson  <prj@mit.edu>
+
+       * client-src/sendbackup.c (check_status): when checking whether
+       return status 1 is valid for dump, make sure it was *not* tar that
+       was running.
+
+1998-05-28  Tom Lear <toml@accesscom.com>, John R. Jackson  <jrj@purdue.edu>
+
+       * man/amcheck.8.in: document new -Maddress command line flag.
+       * server-src/amcheck.c (usage, main): add -Maddress command line
+       flag to send mail to a specific address instead of mailto from
+       amanda.conf.
+
+1998-05-27  John R. Jackson  <jrj@purdue.edu>
+
+       * man/amrestore.8: update for host/disk/date triplets.
+       * recover-src/extract_list.c (extract_files_setup): pass datestamp
+       argument in new position and without -d.
+       * restore-src/amidxtaped.c (main): remove -d checks.
+       * restore-src/amrestore.c (restore, usage, main): fix file descriptor
+       leak, move datestamp to host/disk triplet and allow all to be repeated.
+
+1998-05-27  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/killpgrp.c (main): wait for either SIGTERM or EOF on
+       stdin.
+
+       * client-src/sendsize.c (getsize_dump): close the other end of
+       killpgrp's stdin pipe before trying to kill it, because we just
+       can't kill it.
+
+       * configure.in (HAVE_HPUX_SCSI): check whether sys/scsi.h actually
+       supports HP/UX-like changer commands.
+
+       * config/acconfig.h (HAVE_HPUX_SCSI): indicates HP/UX-like changer
+       interface is supported.
+
+       * changer-src/scsi-hpux.c: check for HAVE_HPUX_SCSI instead of
+       HAVE_SYS_SCSI_H.
+
+1998-05-25  Allen Briggs  <briggs@canolog.ninthwonder.com>
+
+       * changer-src/chg-manual.sh.in (ONLINEREGEX): add `^er=0$' for
+       NetBSD's mt
+
+1998-05-23  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendsize.c (getsize_dump): killpgrp must be direct
+       child of sendsize, otherwise sendsize won't be able to kill it.
+
+1998-05-23  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in (bcopy, bzero, fread, fwrite, vfprintf, vprintf,
+       vsprintf): check for these in stdlib.h
+       (memmove): check for it in strings.h
+       
+       * common-src/amanda.h (memmove): fix declaration of memmove, so as
+       to be compatible with the ones in common-src/memmove.c and
+       regex-src/fake/memmove.c
+       
+       reported by Tim Potter <tpot@acsys.anu.edu.au>
+
+1998-05-20  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * client-src/sendbackup.c (check_status): when checking whether dump 
+       returned 1, make sure it was not tar; #ifdef'ed out the code that
+       ignores exit status 2 from gnutar (will be compiled in only if
+       IGNORE_TAR_ERRORS is defined)
+       * client-src/sendbackup-gnutar.c (GNUTAR active filesystem errors): 
+       updated comment; compile in GNUTAR error messages as DMP_NORMAL if
+       IGNORE_TAR_ERRORS is defined; compile in SMBCLIENT error messages as 
+       DMP_NORMAL if IGNORE_SMBCLIENT_ERRORS is defined.
+       
+1998-05-20  Tom Lear  <toml@accesscom.com>
+
+       * client-src/sendbackup.h (tarpid): new variable, used to check
+       whether it is gnutar that is running
+       * client-src/sendbackup-gnutar.c (start_backup): set tarpid when
+       starting gnutar
+       * client-src/sendbackup.c (check_status): if gnutar returns 2,
+       ignore the error
+
+1998-05-19  Jean-Louis Martineau <martineau@IRO.UMontrealCA>
+
+       * client-src/amandad.c: set parse_errmsg when unexpected packet
+       * recover-src/amrecover.c: overflow in clean_pathname()
+       * recover-src/extract_list.c: add log in delete_file().
+       small bug when call clean_pathname()
+       * server-src/amindexd.c: ORLD command is not working
+       * server-src/dumper.c: fixe overflow
+
+1998-05-17  Alexandre Oliva  <oliva@dcc.unicamp.br>
+
+       * configure.in: do not check for MAXFILESIZE
+       * config/acconfig.h: do not define MAXFILESIZE
+       * server-src/conffile.c: use INT_MAX instead of MAXFILESIZE
+       * example/amanda.conf.in: ditto
+
+       * server-src/driver.c (interface_state): new function; print the
+       free bandwidth for each interface.
+       (short_dump_state): call interface_state before holdingdisk_state
+
+       * ChangeLog: renamed from CHANGES.  Original entries follow.
+
+       fix skip-incr handling so that reporter reports SKIPPED
+       instead of missing result.
+       -Jim Simmons <s4i@sws6.ctd.ornl.gov>
+
+       split big dumps ( > MAXFILESIZE ) in multiple files on holding disk. 
+       new chunksize parameter in holdingdisk description of 
+       the amanda.conf file.
+       -J-L Martineau <martineau@IRO.UMontreal.CA>
+
+       an amstatus command that give the current state of a run.
+       -J-L Martineau <martineau@IRO.UMontreal.CA>
+
+       possibility to amflush multiple runs on one tape.
+       possibility to select dump by datestamp in amrestore (-d datestamp).
+       -J-L Martineau <martineau@IRO.UMontreal.CA>
+
+       amidxtrm keep index of all active tapes as listed in tapelist file.
+       -J-L Martineau <martineau@IRO.UMontreal.CA>
+
+       the tapelist file keep every active tapes.
+       "amadmin reuse" and "amadmin no-reuse" to mark tapes you want
+       to keep for a long time.
+       -J-L Martineau <martineau@IRO.UMontreal.CA>
+
+       amlabel will not overwrite an amanda tape.
+       The -f flag allow to overwriting an amanda tape.
+       -J-L Martineau <martineau@IRO.UMontreal.CA>
+
+       be consistent and use 1048576 as a dump size everyplace instead of
+       100000 in some places (mostly cosmetic).  -JJ
+
+       negative numbers are now accepted in the configuration file
+       parser.  -oliva
+
+       allow a total estimate time-out to be specified.  -oliva
+       Suggested by Martyn Johnson <Martyn.Johnson@cl.cam.ac.uk>
+
+       fix amtoc behavior in case of failed reads.
+       -Niek Rijnbout <niek@knoware.nl>
+
+       index files are now stored in a directory tree ala curinfo instead
+       of a flat namespace. -JJ
+
+       amrecover will now restore files using SAMBA.
+       -Rob Riggs <rob@devilsthumb.com>
+
+       VXDUMP needs not be run as root, so it no longer enables
+       rundump automatically.  -oliva
+
+       new `killpgrp' setuid-root program.  It is used to kill
+       VDUMP, VXDUMP and XFSDUMP or with-rundump DUMP estimates in a
+       safe manner.
+       -Joerg Behrens <jbehren@umpa06.gwdg.de> & oliva
+
+       fixed amrmtape so that it will delete from tapelist only the
+       entry that corresponds to the specified tape, not others that
+       contain the tape name as a substring.
+       -Nick Hibma <nick.hibma@jrc.it> & oliva
+
+       Added support for FreeBSD dump -h flag (honor nodump).
+       -James E. Housley <housley@pr-comm.com>
+
+       Added support for ZFTAPE on Linux.
+       -Albrecht Gebhardt <agebhard@zidsrv.sci.uni-klu.ac.at>
+
+       Added support for printing tape labels.
+       -Scott Mesches <mesches@allison.Colorado.EDU>
+
+       Do not let amrecover die because of SIGPIPE if the pager terminates
+       early during a long listing.  Use the PAGER environment variable if
+       available, else "more".  -JJ
+
+       Change log() calls to log_add() so it does not conflict with the math
+       function of the same name.  Replace pname global variable with two
+       functions to set/get.  Get rid of libamnolog.  -JJ
+
+       chg-chio was renamed to chg-scsi, and now it will support not
+       only chio.h, but also tape changer interfaces available on
+       HPUX, Solaris 2.5, IRIX and possibly others.  Currently, only
+       chio and HPUX are implemented.
+       -Eric Schnoebelen <eric@cirr.com>
+
+       Numerous bugs/errors were fixed in chg-chio/chg-scsi.  it now
+       properly responds to -eject requests, among other things.
+       -Eric Schnoebelen <eric@cirr.com>
+
+Version 2.4.0p1
+
+       updated to libtool 1.2a.  -oliva
+
+       fix kerberos encryption to work.  -Chris Ross <cross@uu.net>
+
+       add --with-owner option to optionally not have things owned by
+       the amanda user.  (meant to be in 2.4.0) -kovert
+
+       only call initgroups() if it is available.  -oliva
+
+       check whether GNUTAR_LISTED_INCREMENTAL_DIR is a directory.
+       -oliva, reported by J.A. Gutierrez <spd@gtc1.cps.unizar.es>
+
+       amindexd no longer considers prefixes of hostnames as valid
+       hostnames. -oliva
+
+       fix strappend2 so that it accepts a NULL first argument.
+       -Rob Riggs <rob@devilsthumb.com>
+
+       pass kerberos encryption switch to client.
+       -Fredrik Jönsson <fjo@nada.kth.se>
+
+       rename afree to amfree, to work around IRIX 6.4's afree.
+       -oliva, reported Stephan P. Martin <smartin@schlund.de>
+
+       implement `strategy skip' just like `ignore'.
+       -oliva,
+       reported by Michael O'Shaughnessy <mikeo@emg.sms.siemens.com>
+
+       amcheck now checks whether COMPRESS_PATH is executable, which
+       would prevent server-compression and indexing from working.
+       -oliva, reported by Peter Schultze <peter@mbi.ucla.edu>
+
+       fixed dump estimate regular expression for DU 4.0.
+       -Andreas Schmitz <schmitz@theorie.physik.uni-wuppertal.de>
+
+Version 2.4.0
+
+       fixed memory corruption error in amtape.
+       -oliva
+
+       fixed VXDUMP support.
+       -Andrew Ivanov <ivanov@mics.msu.su> & oliva
+
+       typos fixed in chg-chs.
+       -David Barr <dbarr@simplex.com>
+
+       chg-mtx now prints error message if tapedev or changerdev must
+       be defined.
+       -Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>
+
+       fixed amflush problem, reported by Dietmar Goldbeck
+       <dietmar@telemedia.de>  -oliva
+
+Version 2.4.0-980319
+
+       chg-mtx should use changer-dev if specified.
+       -Steve Khoo <steve@gordian.com>
+
+       flex-related backward-compatibility problem fixed.
+       -Norman K Scherer <nsche@seros-48.hac.com>
+
+       ported to RISCOS 4BSD.  -Harlan Stenn <Harlan.Stenn@pfcs.com>
+
+       when amrecover starts up, it will warn you $CWD is not the root
+       of the selected filesystem.  -oliva
+
+       removed all uses of #elif, because some C compilers won't
+       handle it correctly. -Gunther Felkel <G.Felkel@edelmann.de>
+
+       fixed VDUMP-only (no DUMP defined) estimates.
+       -Joern Behrens <jbehren@umpa05.gwdg.de>
+
+       ported to UnixWare.  -Jeff Moscow <jeff@rtr.com>
+
+       improved vxdump support so that rundump will be used for vxfs
+       filesystems only, and it will be enabled automatically.  -oliva
+
+       various portability problems fixed.
+
+       taper will now log reason for tape error to log.<DATE> file,
+       in addition to amdump.<n>.
+       -Liudvikas Bukys <bukys@cs.rochester.edu>
+
+       amflush now correctly updates the info database.  -oliva
+       reported by Liudvikas Bukys <bukys@cs.rochester.edu>
+
+       sendsize now wait()s for tar and samba child processes.  -oliva
+       reported by Brian Morris <brian@mvhs.fuhsd.org>
+
+       ensure that `amadmin find' reports multiple backups performed on
+       the same day in the correct sequence.
+       -Liudvikas Bukys <bukys@cs.rochester.edu>
+
+       if backup server has multiple IP addresses, security code
+       might reject it.  -Gunnar Gunnarsson <gunnar@ki.ericsson.se>
+
+       vdump would not work.  -oliva
+
+       kerberos support was broken.  -mike
+
+Version 2.4.0-980222
+
+       retry tape open on AIX if it fails with EAGAIN errno.
+       -Francois Morris <Francois.Morris@lmcp.jussieu.fr>
+
+       fix amrmtape so that it behaves well when files to amflush
+       remain.  Reported by Dietmar Goldbeck <dietmar@telemedia.de>
+
+       retry tape rewind on FreeBSD.  -Bob Willcox <bob@prm.com>
+
+       read all output from amrestore otherwise, instead of the
+       beginning of the next tape section, it would read garbage.
+       -Terje Malmedal <tm@odin.funcom.com> & oliva
+
+       formatting error in amoverview fixed.
+       -Terje Malmedal <tm@odin.funcom.com>
+
+Version 2.4.0b6p4
+
+       use vdump to dump advfs filesystems only.  add support for vdump
+       indexes.
+       -Martyn Johnson <Martyn.Johnson@cl.cam.ac.uk> & oliva
+
+       change index generation commands so that they are less prone
+       to be fooled by blanks or strange characters in filenames.
+       -oliva
+
+       check whether exclude-list file exists before calling gnutar.
+       If it does not, log a message to debugging file and discard it.
+       selfcheck should check for that too, and print a warning message,
+       but this is left for a future version.  -oliva
+
+       fix sendbackup-gnutar crashing problem.  -oliva
+
+       ensure that, in case of tape failure when dumping to tape, no
+       incremental relative to the failed backup is performed.
+       -oliva & Liudvikas Bukys <bukys@cs.rochester.edu>
+
+       Fix buffer use and write() error handling in the index pipeline.
+       -Dietmar Goldbeck <dietmar@telemedia.de>
+       & Lars Fenneberg <lf@elemental.net>
+
+       new index generation commands.  -oliva
+
+Version 2.4.0b6p3
+
+       accept curses and ncurses in addition to termcap for readline
+       support, just as readline itself does.  -oliva
+
+       fix NO-ROOM handling when Kerberos encryption is enabled.
+       -oliva & Eric Siegerman <erics@now.com>
+
+       patch file for automake 1.2d provided. -oliva
+
+       sendbackup.debug now contains the argument list of child
+       processes. -oliva
+
+       wait() for child processes, such as server compressor, before
+       accepting other commands.
+       -Liudvikas Bukys <bukys@cs.rochester.edu>
+
+       amrecover will print an error message if it is not run by root.
+       It will not crash if you `pwd' before selecting a disk.  -oliva
+
+       updated to libtool 1.0i. -oliva
+
+       fixed tape block size of vxdump on HPUX 10.20.
+       -Andrew Ivanov <ivanov@mics.msu.su>
+
+       Use "a" mode instead of "w" for the fdopen of the debug file.
+       -David Lamkin <drl@net-tel.co.uk>
+
+       allow multiple concurrent gnutar backups, by fixing amandates
+       locking mechanism.
+       -Liudvikas Bukys <bukys@cs.rochester.edu>
+
+       amdump should check for a hold file, as says the man-page.
+       -oliva
+
+       fix automatic enabling of USE_RUNDUMP for systems that require
+       this.  xfsdump support no longer requires USE_RUNDUMP to be
+       defined, rundump will be enabled and used for xfs filesystems
+       even if USE_RUNDUMP is not defined, unless XFSDUMP is not defined.
+       This seems to have completely solved the xfsdump problems.
+       -oliva
+
+       when USE_RUNDUMP is enabled, instead of checking for read or write
+       access in selfcheck, just test for the existence of disk devices.
+       -oliva
+
+       fixed code that computed the dump size when incomplete
+       writes occurred in dumper.  -Eric Siegerman <erics@now.com>
+
+       amplot no longer crashes if there's no holding disk. -oliva
+
+Version 2.4.0b6p2
+
+       fix xfsdump index generation command.
+       -Robert Tarrall <tarrall@bamboo.colorado.edu>
+
+       tape device wouldn't rewind if opened O_WRONLY.
+       -Palle Girgensohn <girgen@partitur.se> & oliva
+
+       use setpgid instead of setpgrp if available
+       -Mark Woodford <woodford@uniprise.com> & oliva
+
+       chg-mtx will check whether slot 6 is a cleaning tape or not.
+       -Martyn Johnson <Martyn.Johnson@cl.cam.ac.uk>
+
+       amrmtape updated to text database.  -oliva
+
+       incorrect NO-ROOM error when dumping directly to tape fixed.
+       -oliva
+
+       --with-user and --with-group become are now required.  -oliva
+
+       patch-system script much more configurable.  -oliva
+
+       amindexd must get an exact match for diskname.
+       -Richard Kail <e8903122@student.tuwien.ac.at> & oliva 
+
+       fix serial number message in amflush
+       -Liudvikas Bukys <bukys@cs.rochester.edu>
+
+       removed backslashes from inside macro calls.
+       un-indented # directives.
+       -Gregory Neil Shapiro <gshapiro@WPI.EDU>
+
+       bsd-security is now enabled by default.  -oliva
+
+       fixed estimate command for XFSDUMP.
+       -Mark Radleigh <radleigh@image.ucr.edu>
+       & Jeff Moskow <jeff@rtr.com>
+
+Version 2.4.0b6p1
+
+       documented etimeout configuration option.  -oliva&jrj
+
+       prevent a few crashes in dumper and reporter.  -jrj
+
+       reporter would report the same host and disk for RESULTS MISSING.
+       -martineau
+
+       fix a few file-locking configure bugs.  -oliva
+
+       chg-multi updates and bugfixes.
+       -Liudvikas Bukys <bukys@cs.rochester.edu>
+
+Version 2.4.0b6
+
+       amindexd bugfix -Jos Alsters <Jos.Alsters@sci.kun.nl>
+
+       New --disable-libtool configure option, for those who really don't
+       want libraries to be installed.  Shared libraries won't be
+       built, of course.  -oliva
+
+       samba-related bugfixes.
+       -Klaus Thiele <kth@becker-software.com>
+
+       xfsdump, DNS and amidxtaped bugfixes. -martineau
+
+       exclude-list support was broken, the filename was not copied
+       to the gnutar argument list.
+       -Stefan Bohm <Stefan.Bohm@rp-online.de>
+
+       chg-chio still thought it was seagate-changer, and contained a
+       few bugs.  -Tim Tsai <tim@futuresouth.com>
+
+       New file docs/RESTORE, by Daniel Moore <dmoore@jeffco.k12.co.us>
+
+Version 2.4.0b5
+
+       Make sure amverify waits for the tape device to be ready before it
+       starts reading each section. -oliva
+
+       Fix amrecover so that it accepts filenames with blanks.
+       -J. Shirk <jshirt@ksu.edu> & oliva
+
+       Add a TIMEOUT config file parameter to replace the hard coded value
+       in planner.  -Daniel David Benson <bensond@ucdavis.edu>
+
+       Change amrecover/amindexd/amidxtaped to require a SECURITY
+       exchange if --with-bsd-security is enabled.  It is done on a
+       reserved port, which means amrecover must be run as root and that
+       amindexd/amidxtaped need an entry for the incoming amrecover in
+       either .rhosts or .amandahosts (Kerberos is not yet supported).  --JJ
+
+       Make our internal TEXTDB the default database style for the infofile.
+       If you wish to keep using a dbm style database use the configure
+       option "--with-db={db,dbm,gdbm,ndbm}".
+       -scott
+
+       Sanitise the disk name in the TEXTDB code.
+       **NOTE** if your infofile database uses TEXTDB (which has only been
+                available since Amanda-2.4.0b1) and you have '/'s in the
+                first field in disklist you will need to 'amadmin export'
+                the data using the old version of Amanda, 'mv' the old
+                database out of the way and 'amadmin import' it back again
+                using the new version.  When you are happy with the new
+                version you may delete the old database.
+       -scott
+
+       Get rid of DEV_ROOT/DEV_RROOT and figure out the raw name on the
+       fly by trying a leading 'r' before each path element one at a time
+       until we find a character device.  This should handle all the current
+       cases plus things like Solaris DiskSuite that have /dev/md/rdsk/xxx
+       names.  -JJ
+
+       Change kill logic in sendsize to try TERM first, then KILL if that
+       does not get dump's attention.  This fixes a problem on AIX 4.x
+       where dump was always getting a KILL and leaving orphaned message
+       queues, which would eventually run the system out of resources.  -JJ
+
+       Extensive buffer management, bug and defensive coding overhaul
+       including:
+           * Use proper fgets/fread/read buffer size.
+           * Wrote agets and areads to get a line without buffer overflow
+             and changed most gets/fgets and some read calls to use it.
+           * Replaced all *scanf("...%s...") with explicit pointer work.
+           * Replaced most fixed size buffers with dynamic ones.  This has
+             no doubt introduced some memory leaks.
+           * Replaced most sprintf calls with vstralloc (new routine).
+           * Added overflow checks to some remaining explicit buffer
+             management.
+           * Made almost all read() and write() calls into loops to handle
+             short and broken up transfers.
+           * Fixed potentially uninitialized fstype field.
+           * Added more sanity checks when parsing various things, including
+             converting some assert() calls to real code.
+           * The pattern amtrmidx used to find old index files to delete
+             thought the date field was YYYY-MM-DD, but it is YYYYMMDD,
+             so no files were being deleted.
+           * Limited the number of directories listed by amflush to 26 to
+             avoid funny characters in the user prompt.
+           * Changed some of the amrecover routines to soak up the rest of
+             the continuation lines after an error.
+           * If a dumper dies, driver still tries to send a QUIT command
+             which fails because the file descriptor has been closed.
+           * Wrote afree macro that calls free and then sets the pointer
+             to NULL.  Changed most free calls to afree.
+           * Wrote aclose/afclose/apclose macros to do the associated close
+             and then set the argument to something invalid (-1 or NULL).
+           * Check the file descriptor before calling FD_ISSET in dumper.
+             Otherwise it goes to -1 on EOF and FD_* doesn't like that.
+           * Call aclose() after FD_CLR (so the descriptor is not -1).
+       Odds and ends:
+           * Added some TEXTDB support code to the infofile test program.
+           * Set it up so -DPROTO_DEBUG could come from the compiler command
+             line instead of having to modify the source.
+           * Added -t command line flag code to sendbackup.c to support some
+             limited debugging.
+           * Added a test to amcheck to see if the log file is writable
+             (if it already exists).  During debugging, I keep leaving one
+             around owned by root :-).
+           * Changed upper limit on close loops from 255 to FD_SETSIZE.
+             This probably needs some more study.
+       -JJ
+
+       If krb4 auth was compiled in but not enabled, clients would hang
+       forever.  -Aidan Cully <aidan@panix.com>
+
+       Make sure SAMBA will not clear archive bits when performing an
+       incremental backup, so any incremental will be a level 1.
+       -martineau
+
+       Add a LOGDIR option to amanda.conf and use it to replace the
+       --with-logdir option to configure (this was only used for the
+       amdump files) and the logfile option in amanda.conf.  Log
+       files are now LOGDIR/log and amdump files are LOGDIR/amdump.
+       Note: if there is a LOGFILE option in amanda.conf it has its
+       filename removed and is used as the LOGDIR (eg, if you have
+       "logfile /usr/adm/amanda/log" in amanda.conf it is translated to
+       "logdir /usr/adm/amanda" instead).  This should not cause a
+       problem for most sites.
+       -scott
+
+       Remove --with-dbdir option from configure.  This was only used
+       to setup things for the man pages and example files.  Oh.. and
+       amrmtape.  Fix this as well.
+       -scott
+
+       Remove --with-indexdir option from configure.  This is obtained
+       from amanda.conf at run time.  Also fix things so that it *is*
+       obtained from amanda.conf in all cases.
+       -scott
+
+       This is no longer tested on configure.in, since it is
+       expressly forbidden to include kernel headers under glibc,
+       according to Matthias Urlichs <smurf@noris.de>.  However, Eric
+       Doutreleau <ed@cti.ecp.fr> said he needed to include this
+       header file in order to build amanda on
+       sparc-unknown-linux-gnu.  -oliva
+
+       It is now possible to specify a username to be used to backup
+       up with samba.
+       -Jean-Louis Martineau <martinea@iro.umontreal.ca>
+
+       Make sure dumper replies with ABORT_FINISHED when a PORT-DUMP
+       is aborted because of tape error.
+       -Michael C. Povel <Michael.Povel@hub.de>
+
+       Amcheck checks only for the needed features.
+       -Jean-Louis Martineau <martinea@iro.umontreal.ca>
+
+       Performance and memory-usage improvements to amrecover.
+       -Jean-Louis Martineau <martinea@iro.umontreal.ca>
+
+       Use extended regular expressions.
+       -Noel Hunt <noel@jpmorgan.com>
+
+       Fixed regular expressions for samba support.
+       -Brian Fernald <fernald@nsi.edu>
+
+       Fixed a few bugs that caused arithmetic exceptions in planner.
+       -Bob Willcox <bob@luke.pmr.com>, Evan Champion
+       <evanc@synapse.net>, scott and oliva
+
+       amrecover should now be able to handle GNUtar restores.
+       -Jean-Louis Martineau <martinea@iro.umontreal.ca>, plus
+       incremental (-G) patch by Lars Fenneberg <lf@elemental.net>
+
+       Ported to SINIX (Reliant Unix V5.43).
+       -Michael Schmitz <mschmitz@iname.com>
+
+       Configure now looks for large file support and will use it under
+       Solaris 2.6 and above.
+       -Blair Zajac <blair@gps.caltech.edu>
+
+       Compatibility problems fixed for:
+               SCO OpenServer 5.0.2: Paul Gampe <paulg@twics.com>
+
+Version 2.4.0b4
+
+       New changerfile and changerdev configuration keywords, that
+       allow changer scripts to be configured in the main amanda
+       configuration file.  Each changer script has been adapted, so
+       that it uses those flags whenever possible.  Also,
+       documentation about built-in scripts has been added to
+       docs/TAPE.CHANGERS.  -oliva & Eric Schnoebelen
+       <eric@egsner.cirr.com>
+
+       --with-debugging now accepts a directory name, where debugging
+       files should be stored.  -John R. Jackson <jrj@cc.purdue.edu>
+
+       Compatibility problems fixed for:
+               NextStep 3.3: Fabrice GAILLARD <gaillard@ina.fr>
+               SCO OpenServer V5: Christopher B. Olsen <colsen@compus.com>
+               AIX: Georg Rehfeld <georg@wmd.de>
+
+       Planner would core dump if it had to delay dumps.  -Georg
+       Rehfeld <georg@wmd.de>
+
+       Added patch for samba to support very long filenames.  -Todd
+       Pfaff <todd@edge.cis.mcmaster.ca>
+
+       Added VXDUMP support to estimate program.  -oliva & John
+       R. Jackson <jrj@cc.purdue.edu>
+
+       Fixed amflush so that it cd's to the configuration directory
+       before invoking reporter.  -oliva
+
+       driver no longer opens the infofile, so a deadlock is
+       prevented.  -oliva & John R. Jackson <jrj@cc.purdue.edu>
+
+       Fixed typo in sendbackup-dump that would prevent compilation
+       if either xfsdump or vxdump were enabled.  -oliva
+
+       Debugging messages produced by sendbackup are no longer
+       included in the dump stream.  -oliva
+
+       amrestore should wait for the child process to die before
+       re-opening the tape device.  -Dietmar Braun
+       <dietmar@tin-lizzy.hig>
+
+Version 2.4.0b3 
+
+       fixed race condition in debug file open operation.  -oliva and
+       Thomas Schmeidl
+
+       exclude-list and exclude-file are correctly handled by
+       sendsize.  -oliva and Johann Klasek <jk@auto.tuwien.ac.at>
+
+       fix some kerberos4 problems; no longer require low ports for
+       kerberized connections; now use amanda@REALM instead of
+       amanda.amanda@REALM in .klogin's.  -kovert
+
+       amrecover no longer depends on GNU flex library.  -oliva
+
+       Ensure that malloc(0) is not called.  -Wolfram Schmidt
+       <Wolfram.Schmidt@iao.fhg.de>
+
+       Compression is now performed where specified, and server
+       compress best specifications are obeyed. -oliva
+
+       genversion now correctly recognizes the selected locking scheme.
+       -Thomas Schmeidl <schmeidl@nwp.kwu.siemens.de>
+
+Version 2.4.0b2
+
+       Several bugfixes by John R. Jackson <jrj@cc.purdue.edu>
+
+       AIX's restore support added to amrecover.  -David B. Anderson
+       <dbanders@mail.physics.utah.edu>
+
+       Dump process would not be killed unless it supported the -E
+       flag (flipped #ifdef): fixed.  -Steve Bower <sbower@raytheon.com>
+
+       --with-testing now supports a trailing argument, that
+       specifies the a string to be appended to service names.  -oliva
+
+       Recent versions of Samba require additional arguments so that
+       estimates and total sizes are logged to stdout, not to syslog.
+       -Ernie Oporto <ernie_oporto@MENTORG.COM> & Norbert Holzknecht
+       <Holzknecht@fs31.vdeh-bfi.de>
+
+Version 2.4.0b1
+
+       Improved planner backup-delaying mechanism.  -scott
+
+       Concurrent estimates are now supported.  -oliva
+
+       Shared library support included with GNU libtool.  -oliva
+
+       New hard-link-based locking mechanism for operating systems
+       that do not support standard locking system calls.  -scott
+
+       New configuration file format, simpler and easier to
+       extend.  -scott
+
+       New curinfo database format that uses only text files.  The
+       old dbm format is used by default, though.  -scott
+
+       DGUX support. -Brian Harvey <bharvey@raven.phs.com>
+
+       Tentative HPUX vxdump support.  -oliva
+
+       Integrated amgetidx into dumper/sendbackup protocol.  This
+       ***breaks backward compatibility***!  -oliva
+
+       Have sendbackup-dump and sendbackup-gnutar list the actual
+       program that should be used to restore a file from a backup
+       instead of just listing restore or gtar. -blair&oliva
+
+       Have configure check for the initgroups() declaration in
+       unistd.h in addition to grp.h and sys/types.h, which is where
+       some OSes have the declaration. -blair
+
+       SAMBA backups wouldn't succeed if GNUTAR listed incrementals
+       were enabled.  SAMBA password file can now specify workgroup
+       and may contain comments.  -oliva
+
+       Fixed xfsdump support. -oliva
+
+       Fixed srvcompress option. -oliva
+
+       Fixed exclude/exclude-list support. -oliva
+
+       Change umask to 066 before creating index file in /tmp. -oliva
+
+       Fixed autoconf for gdbm on linux. -oliva
+
+       configure now seeks out a few possible locations for
+       kerberos4 includes and tries to find the correct path if
+       the kerberos bits have been installed.  It's possible for
+       someone to just specify the root of a kerberos tree for
+       where the bits live, as well. -kovert
+
+Version 2.3.0.4
+
+       Have bsd_security_ok() in amandad return 1 when BSD security is
+       not turned on.  Patch from Michael C. Grant
+       <mcgrant@rascals.Stanford.EDU>.
+
+       Add a configure option, --with-db, which lets the user specify
+       the database library to use.  The available codes to look for
+       are db,dbm,gdbm,ndbm.  The new configure code goes to a lot
+       more length to find pairs of header files and libraries.  If a
+       header file exists and the library does not, but dbm_open() is
+       found by linking against -lc, then that header file is used.
+       Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Fixed bug at line 158 where selfcheck was testing that the
+       result returned by open() was nonzero.  The correct thing to do
+       is check for non-negative values returned by open().  Changed
+       the "ERROR" in line 169 to "OK" to prevent selfcheck from
+       flagging the non-existence of /etc/amandapass as an error.
+       Using "OK" in this line flags this condition as an informative
+       statement rather than an error - which is to say this will be
+       reported along with other errors but it isn't enough in itself
+       to generate an error report.  The reason that I think this is
+       the right fix is because although every Amanda client is
+       capable of backing up PCs using smbclient it isn't the case
+       that we will back up PCs with every Amanda client.  This also
+       implies that we don't want to have /etc/amandapass files on all
+       these machines either.  If an Amanda client does have a samba
+       "//host/share" entry in its disklist file then selfcheck will
+       flag the non-existence of the /etc/amandapass file on line 105
+       when it attempts to check that partition, so I believe that
+       this is a safe fix.  Patch from Michael Brantley
+       <Michael-Brantley@deshaw.com>.
+
+       Have all calls to gethostname() leave the result in character
+       arrays of length 1025.  This will make sure that gethostname
+       behaves correctly.  Patch from  blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Have amrecover.c include history.h or readline/history.h if
+       configure finds it.  Patch from blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Have Amanda use cat if gzip and compress cannot be found.  In
+       this case, do not #define COMPRESS_FAST_OPT, COMPRESS_BEST_OPT,
+       or UNCOMPRESS_OPT as "" since cat will look look for a file by
+       the name of "".  Place #ifdef's around code that uses any of
+       the _OPT defines.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Rewrite amgetidx to use amandad instead of rsh/rcp.  amgetidx
+       now only gets the index files from a given day.  It now takes
+       two optionally arguments <on day> or <ago days>.  <on day> lets
+       the user specify the day in one of the forms YYYYMMDD MMDD DD
+       YYYY-MM-DD --MM-DD ---DD.  <ago days> gets the files from days
+       days ago.  Have configure look for an appropriate directory to
+       use for the temporary files on the clients.  Use /var/tmp, then
+       /usr/tmp, and if neither of those exist, then use /tmp.  Have
+       selfcheck check if the index holding directory has enough space
+       in it.  Add a new program called sendindex which sends the
+       index files.  Add the file docs/INDEXING which describes the
+       index code.  Patch from Alan McIvor <alan@auck.irl.cri.nz>.
+
+       Have configure set up mt to use either the -f or the -t option
+       depending upon the operating system.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Include the amanda_tapetypes.txt file as docs/TAPETYPES.  File
+       composed by Chris Stacey <chris@snrc.uow.edu.au>.
+
+       Allow certain dumptypes to be kicked off at specific times.
+       Add a new, optional, parameter to the dumptype description in
+       the config file.  The parameter is called "starttime" and takes
+       one argument which is a time of day (local timezone) formated
+       as either hhmm or hmm (no `.'s, no `:'s, just an integer).
+               define dumptype comp-user-2am {
+                       comment "Non-root partitions on fast machines"
+                       options compress-fast
+                       priority medium
+                       starttime 0200
+               }
+       Any partitions listed in disklist with this dumptype will be
+       fired off no earlier than 2am.  If 2am today is less than 43200
+       seconds past (12 hours ago) it will assume you meant 2am today
+       and fire the dumps off right away.  But if 2am today is more
+       than 12 hours in the past, it will wait till 2am tomorrow.
+       Patch from Brad Huntting <huntting@misc.glarp.com>.
+
+       Totally rewrite the socket buffering code for dumper.
+       Eliminate SO_SNDTIMEO and SO_RCVTIMEO setsockopt calls.  Remove
+       the check for HAVE_SO_SNDTIMEO from configure.  Add a new
+       option to configure named --enable-buffered-dump to enable this
+       code.  Patch from Brad Huntting <huntting@misc.glarp.com>.
+
+       Have amflush call setsid() to detach amflush from the
+       controlling terminal.  Patch from Ken Laprade
+       <klaprade@harris.com>.
+
+       Have configure correctly work on systems where dbm_open is in
+       libc.  Patch from Farzad Farid <farzy@sgip.fr>.
+
+       Patches to amrmtape which remove C style comments and let the
+       script remove a tape if there is only one tape in the tapelist
+       file.  Patch from Andrew A. Ivanov <IVANOV@mics.msu.su>.
+
+       Sprintf formatting error in amgetidx fixed.  Patch from Yossi
+       Gottlieb <yogo@xpert.com>.
+
+       I'm using a Sony SDT/STL-7000 4mm DAT changer.  I could not
+       find any method of directly controlling the device, except for
+       simply using the 'offline' mt command for advancing to the next
+       tape.  Using this method, however, I could not go beyond the
+       last cassette (that is, to roll back to the first one).  This
+       means the device is currently being used as a simple gravity
+       changer, only able to change forward.  The chg-generic.conf
+       should list the default tape device for all slots, disable
+       'needeject', enable 'gravity' and enable the new option named
+       'multieject'.  Patch from Yossi Gottlieb <yogo@xpert.com>.
+
+       Update the example chg-generic.conf file to include comments
+       that describe how to use the multieject feature of the script.
+       Patch from Yossi Gottlieb <yogo@xpert.com>.
+
+       Protocol seems to loop when a A_TIMEOUT occurs because
+       p->reqtries was not being decremented.  Problem noted by Neal
+       Becker <neal@ctd.comsat.com>.
+
+       About half the calls to gethostname() in Amanda fail to
+       null-terminate properly.  This patch makes them all
+       consistent.  In addition it updates sendbackup-dump and
+       sendbackup-gnutar so they handle USE_FQDN is a way consistent
+       with the amindex stuff.  In particular when USE_FQDN is set,
+       the dump clients will not truncate their hostname before
+       putting it in the dump headers.  My patches to amflush are
+       already in the Amanda betas so amflush should be able to match
+       up both FQDN and non-FQDN clients against FQDN and non-FQDN
+       disklist files.  I also fixed an error message that was
+       attributed to gethostname when it actually came from
+       getpeername.  Patches from James Mathiesen
+       <james@nyc.deshaw.com>.
+
+       I have run into the problem, on a Linux system, where the first
+       time I run configure it generates valid Makefiles and Amanda
+       compiles without problem.  If I run configure again, or I alter
+       a Makefile.in or something which causes autoconf to be called,
+       the resulting Makefiles are no good - the programs in
+       server-src don't finish linking because there is no dbm
+       library.  That is, the first time through configure -lgdbm is
+       added to LIBS but the second, and any subsequent times, it is
+       not.  Patch from Alan McIvor <alan@auck.irl.cri.nz>.
+
+       I've just found a bug that has prevented Amanda from running on
+       my site for almost one week.  Just after a dumper replied that
+       it timed-out, the driver would send it another dump request.
+       Then the driver would log to amdump an event of receiving a
+       message from the dumper, but that message would be empty, the
+       holding file for the requested filesystem would not exist, and
+       driver would quit.  It turned out that the problem was that
+       dumper started to close its sockets (datafd, mesgfd and outfd)
+       since release 2.3.0.4b3.  outfd is initialized before invoking
+       startup_dump, but it is sendbackup_response, intended to be
+       invoked by the amandad protocol driver, that opens sockets and
+       initializes datafd and mesgfd.  If sendbackup_response is never
+       run (because the amandad request times out), datafd and mesgfd
+       will not be initialized, so they may contain already closed
+       (and possibly already reopened) file descriptor numbers or
+       still be uninitialized, containing any garbage, but usually 0
+       --- but 0 is stdin, used for reading commands from the driver,
+       it should not be closed!  I've solved the problem by
+       initializing them to -1 in startup_dump.  Patch from Alexandre
+       Oliva <oliva@dcc.unicamp.br>.
+
+       Include declarations for select(), bind(), connect(), fread(),
+       fwrite(), getopt(), getpeername(), getsockname(), getsockopt(),
+       initgroups(), listen(), lstat(), mktemp(), mktime(), puts(),
+       recvfrom(), select(), sendto(), setpgrp(), setsockopt(),
+       shmat(), shmctl(), shmdt(), shmget(), socketpair(), sscanf(),
+       strftime(), strncasecmp(), system() if the system does not
+       declare these in any header files.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Have configure correctly substitute for DB_DIR and LOG_DIR in
+       example/amanda.conf when --prefix was not used.  Problem noted
+       by Philippe Charnier <charnier@xp11.frmug.org>.
+
+       Include seagate-changer.c from Larry D. Pyeatt
+       <pyeatt@cs.colostate.edu>.  This program was written to control
+       the Seagate/Conner/Archive autoloading DAT drive.  This drive
+       normally has 4 tape capacity but can be expanded to 12 tapes
+       with an optional tape cartridge.  This program may also work on
+       other drives.  This program works for me under Linux with Gerd
+       Knorr's <kraxel@cs.tu-berlin.de> SCSI media changer driver
+       installed as a kernel module.  The kernel module is available
+       at
+       http://sunsite.unc.edu/pub/Linux/kernel/patches/scsi/scsi-changer*
+       Since the Linux media changer is based on NetBSD, this program
+       should also work for NetBSD, although I have not tried it.  It
+       may be necessary to change the IOCTL calls to work on other
+       OS's.
+
+       Add a new configure option, --with-group, which tells Amanda
+       the group to install all files as.  Patch from Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       If --with-bsd-security was not set, then dumper would not find
+       the amanda/udp port to use to connect to clients.  Patch from
+       Alan McIvor <alan@auck.irl.cri.nz>.
+
+       The order of dump programs to search for (ufsdump, vdump, dump,
+       backup) didn't work on AIX systems, where backup should be used
+       but a program named dump exists on the system.  Patch by Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       The configure --with-mmap was not working properly since
+       configure was using the wrong variable to see if the system had
+       a working mmap().  Problem noted by Keith Mitchell
+       <kmitch@weenix.guru.org>.
+
+Version 2.3.0.4b3
+
+       Save the results of getchar() into int's instead of char's in
+       amidxtaped.c.  Patch by Blair Zajac <blair@gps.caltech.edu>.
+
+       Fix sendbackup-gnutar so that it can be compiled with a K&R
+       compiler.  Patch by Blair Zajac <blair@gps.caltech.edu>.
+
+       Since I installed Amanda 2.3.0.4b3, I noticed some annoying
+       messages in amdump:
+               dumper: pid 8696 setsockopt(SO_SNDTIMEO): Invalid argument
+       This is because Solaris 2.5 does declare SO_SNDTIMEO in
+       sys/socket.h, but fails to setsockopt with the given
+       arguments.  Unfortunately, it is not documented, so I could not
+       find out the correct way to do this, so I just added a test in
+       configure to check whether SO_SNDTIMEO works as expected or
+       not.  Patch from Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       Include amplot-2.2.6 written by Olafur Gudmundsson
+       <ogud@tis.com> into Amanda.  Have amplot be configured using
+       configure instead of amplot.conf.  It will be installed if
+       gnuplot and the version of awk configure finds can handle
+       variable assignment from the command line.  I also changed some
+       of the command line options so that the amdump files will not
+       be compressed unless amplot is told to do so on the command
+       line.  It also takes a new command line option, -t, which lets
+       the user set the time of the right side of the plot.  Work done
+       by Blair Zajac <blair@gps.caltech.edu>.
+
+       Made rth-changer check all system calls for valid returns.
+       Patch by Blair Zajac <blair@gps.caltech.edu>.
+
+       amrestore.c and sendbackup-common.c would do an ifdef on
+       HAVE_GZIP, which was no longer being defined if Amanda was
+       using gzip.  Now, define HAVE_GZIP if gzip is being used.
+       Patch by Blair Zajac <blair@gps.caltech.edu>.
+
+       Include a script, amoverview, that outputs an overview of all
+       of the backups done on all of the disks.  Script written by
+       Dave Disser <disser@sdd.hp.com>.
+
+       The prototype for amname_to_fstype() is missing in
+       createindex-dump.c when xfsdump is available.  Patch from Ken
+       Laprade <klaprade@harris.com>.
+
+       Apparently SGI provides a dummy libsun.a that does not really
+       have anything in it.  I guess this tricks configure into adding
+       it to the Makefile.  Have configure not check for libsun.a on
+       SGI systems.  Patch from Ken Laprade <klaprade@harris.com>.
+
+       The global variable overwrite in amcheck.c apparently is seen
+       as a potential conflict with the overwrite() curses function
+       which is apparently in SGI's libtermcap.a.  Declaring the
+       variable static eliminates the warning.  Patch from Ken Laprade
+       <klaprade@harris.com>.
+
+       Add a new configure option, --with-fqdn, which allows Amanda to
+       back up systems in different domains.  This requires that the
+       disklist file have the fully qualified domain names (FQDNs)
+       listed.  Patch from Joe Ammond <Joe.Ammond@ee.gatech.edu>.
+
+       Include rundump, a setuid program that runs dump as root.  This
+       is used under OSF1 systems.  Patch from Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       Install setuid files executable only by the owner and group of
+       the files.  This stops other users from running these programs,
+       making security tighter.  Patch from Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       On FreeBSD 3.0, amanda.h needs to include <sys/types.h> before
+       <dirent.h>.  Problem noted by Keith Mitchell
+       <kmitch@weenix.guru.org>.
+
+       Amanda had a bug regarding the recent addition of support for
+       excluding files in GNUTAR.  planner and sendsize did not
+       understand each other about empty exclusion lists, so there
+       were failures using gnutar, as dump does not support excludes.
+       Patch from Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       Fixed a problem in configure where DUMP was being set to
+       /no/restore/available when no restore program could be found
+       instead of setting RESTORE to this.  Patch from Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       Have no-changer and hp-changer check for the existence of the
+       logging directory before trying to use it.  Patch by Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Patches to have nicer looking Samba support code.  Patch from
+       Michael Zucchi <cismpz@cis.unisa.edu.au>.
+
+       Got Amanda to compile fine on a m88k-motorola-sysv4 system.
+       Patches from Blair Zajac <blair@gps.caltech.edu>.
+
+       In amandad.c, pk_t dupmsg was conflicting with dupmsg in
+       /usr/include/sys/stream.h on an m88k-motorola-sysv4 system.
+       Rename dupmsg to dup_msg.  To keep things consistent, rename
+       inmsg to in_msg and outmsg to out_msg.  Patch by Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Check for the dbm_open declaration in any header file that may
+       contain it.  If it doesn't exist, then declare it and all of
+       the other dbm_ functions.  Check if struct datum is declared in
+       any header files and if it isn't then declare it.  Patch from
+       Blair Zajac <blair@gps.caltech.edu>.
+
+       Have runtar make sure that it is being invoked by the
+       CLIENT_LOGIN user, since it is a suid executable.  Patch from
+       Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       Have selfcheck check for /etc/vdumpdates if vdump is being
+       used.  Patch from Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       If we're on an Ultrix system, then define STATFS_ULTRIX.  Patch
+       by Blair Zajac <blair@gps.caltech.edu>.
+
+       amadmin export produces a full version number (2.3.0.4b2, for
+       instance), while amadmin import expects three integers
+       separated by dots, so it fails to import an exported file by
+       itself.  Patch by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       Sendsize.c would loop forever if debugging was not turned on.
+       Patch from Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       Define STATFS_OSF1 if we are on a *-dec-osf-* system.  Change
+       ifdef OSF1_HANG_BUG to ifdef OSF1_VDUMP, since I'd rather not
+       have too many defines floating around.  Patch by Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       There was a bug in selfcheck.c when Blair installed the Samba
+       support.  I deleted an extra space that was added after
+       SAMBA_CLIENT when the command was being put together.  Fix by
+       Michael Zucchi <cismpz@cis.unisa.edu.au>.
+
+       Add a needed ; to client-src/Makefile.am and
+       server-src/Makefile.am.  Patch from Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       Have planner.c and amcheck.c always get the amanda port number
+       even if BSD security is turned off.  Patch by Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Change the way amgetidx caches host up/down information.  It
+       used to stralloc() a string depending on if the host was up or
+       down.  Now, create two static character arrays, one holding
+       "down" and the other holding "up" and simply point the
+       hostinfo->up pointer to one of the two arrays.  This should
+       save a little memory.  Patch by Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       The Bourne shell in FreeBSD can't handle setting IFS to : and
+       expanding $LOCPATH:$SYSPATH.  Create two new variables before
+       their use called $LOCSYSPATH and $SYSLOCPATH.  Patch by Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Have open_fstab for BSD systems return the value of setfsent.
+       Patch by Blair Zajac <blair@gps.caltech.edu>.
+
+       Configure was searching for the dump program in the following
+       order: ufsdump, vdump, backup, dump.  On HP-UX systems,
+       configure would find backup, which is a valid program but does
+       not do what dump does.  So switch the order of the programs to
+       ufsdump, vdump, dump, backup.  Patch by Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Fixed some dbprintf(()) bugs in amgetidx.c.  Patch by Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Have amrecover.c always declare
+           extern char *optarg;
+           extern int optind;
+       This makes amrecover.c compile on Ultrix systems.  Problem
+       noted by Scott Gasch <scott@cray-ymp.acm.stuorg.vt.edu>.
+
+       Patch to configure to have it recognize gnutar version 1.11.2.
+       Patch from Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+Version 2.3.0.4b2
+
+       Have amcleanup, no-changer, and hp-changer find out where the
+       logging directory, or amdump error file is from getconf instead
+       of using @LOG_DIR@ or @DB_DIR@ from configure.  Problem noted
+       by Joe Ammond <Joe.Ammond@ee.gatech.edu>.
+
+       Remove VarDir=@DB_DIR@ from amrmtape.sh.in, since amrmtape
+       figures out where the curinfo files are from the amanda.conf
+       file.  Problem noted by Joe Ammond <Joe.Ammond@ee.gatech.edu>.
+
+       Include rth-changer, a tape changer script for the Robotic Tape
+       Handling system OEM'd by Andataco (RTH-406).  Script written by
+       Erik Frederick <edf@tyrell.mc.duke.edu>.
+
+       Add a new configure option called --with-pid-debug-files which
+       has Amanda append the process ID to the debugging files placed
+       in /tmp.  The PID will not be appended unless this option is
+       used.  Suggestion by Joe Ammond <Joe.Ammond@ee.gatech.edu>.
+
+       Add a new #define UNCOMPRESS_OPT to pass to UNCOMPRESS_PATH to
+       get compressed standard input decompressed and pass it to
+       standard output.  The configure script only recognized gzip and
+       compress right now, so it will set UNCOMPRESS_OPT to -dc and
+       set UNCOMPRESS_PATH to the same value as COMPRESS_PATH.  Edit
+       all of the files that make use of UNCOMPRESS_PATH to also make
+       use of UNCOMPRESS_OPT now.  Patch by Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       The readline() substitute in amrecover.c when the real
+       readline() code is not available did not return to the caller
+       what the user typed in.  It now does so.  Patch from Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Avoid -lnsl on Irix.  On IRIX 5.x and 6.x systems that have the
+       svr4net module installed, there will be a /usr/lib/libnsl.so
+       present on the system. The configure script looks for this and
+       tosses into the library list if it's there.  It is not
+       advisable to link against libnsl on IRIX unless you really need
+       it for SVR4 networking (TLI/STREAMS). If you _do_ link against
+       it, you should use include '-lc' _before_ '-lnsl'. The reason
+       for this is that libnsl.so also contains the SysV TI-RPC code,
+       which is RPC based on STREAMS/TLI rather than sockets. (Solaris
+       2.x now uses this by default.) TI-RPC has some compatibility
+       functions with the same names as older RPC functions, such as
+       clnt_call(), clnt_create(), clnt_destroy(), and these conflict
+       with the functions in libc.so. The main place this will hose
+       you is NIS: NIS v2 expects the underlying RPC code to use
+       sockets, not STREAMS, and it fails if the TI-RPC symbols in
+       libnsl.so override the RPC symbols in libc.so.  Again, you
+       don't need libnsl.so unless you're actually using STREAMS/TLI
+       or TI-RPC, so in Amanda's case it's safe to just ignore it. If
+       you _do_ need it, you must do 'cc -o foo foo.c -lc -lnsl' in
+       order to make sure the linker resolves the RPC symbol
+       references correctly. The primary symptom of this problem is
+       that things like getpwent(), getgrent() and getnetgrent() stop
+       working in an NIS environment.  To make a long story short: on
+       IRIX, avoid using libnsl. Amanda doesn't need it anyway. So far
+       I haven't encountered a problem with this, but you never know.
+       Note from Bill Paul <wpaul@ctr.columbia.edu>.
+
+       Include patches to have Amanda do incrementals of gnutar based
+       backups.  Patch from Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       Delete the GNUTAR_BROKEN_PIPE from configure and acconfig.h
+       since no code was testing for it.  Patch by Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Have configure check for the number of arguments that
+       gettimeofday takes and have clock.c use the appropriate number
+       of arguments.  Patch by Blair Zajac <blair@gps.caltech.edu>.
+
+       Have sendbackup-common.c include tapeio.h instead of defining
+       BUFFER_SIZE.  Fix by Philip Guenther <guenther@gac.edu>.
+
+       Put in more support for AIX by defining AIX_BACKUP if the
+       system is an AIX system.  Fix createindex-dump.c to pass the -B
+       flag to restore to have it read from standard input.  Problem
+       noted by Bill Paul <wpaul@ctr.columbia.edu>.  Patch by Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Add a regexp for AIX 4's backup in sendbackup-dump.c and
+       sendsize.c.  Patch from Bill Paul <wpaul@ctr.columbia.edu>.
+
+       Add a comment to tapeio.h about BUFFER_SIZE and what it is used
+       for and how people should not change it.  Noted by Bill Paul
+       <wpaul@ctr.columbia.edu>.
+
+       Added a --with-mmap option to force the use of mmap() instead
+       of shared memory support.  Requested by wpaul@ctr.columbia.edu
+       <Bill Paul>.  Patch by Blair Zajac <blair@gps.caltech.edu>.
+
+       On FreeBSD 2.x and 3.x, the SO_SNDTIMEOUT value is too large in
+       dumper.c.  Looking at the kernel source, the maximum value for
+       tv_sec is about 227.  The value used is READ_TIMEOUT/4, or
+       (30*60)/4 == 450 seconds.  This causes setsockopt() to return
+       EDOM (Numerical argument out of domain), and again everything
+       grinds to a halt.  I changed the value from READ_TIMEOUT/4 to
+       READ_TIMEOUT/8, which reduces the SO_SNDTIMEO value to 225.  I
+       haven't extensively tested this yet, but based on eyeballing
+       the kernel source it should work.  Patch from Bill Paul
+       <wpaul@ctr.columbia.edu>.
+
+       In dumper.c:do_dump(), there is code to set the transmission
+       timeout, receive buffer size and receive low water mark on the
+       data socket using setsockopt().  For SO_RECVBUF, the receive
+       buffer size (recbuf) is set to DATABUF_SIZE * 4, which is
+       32*1024*4, or 131072.  On SunOS 4.1.x, this value is too
+       large:  dumper generates a 'no buffer space available' error
+       and everything grinds to a halt.  I took away the '*4', which
+       reduces the size to 32767 bytes, which seems to work.  I'm
+       surprised nobody else has noticed this since it breaks SunOS
+       Amanda servers.  I can only surmise that people aren't using
+       SunOS machines as servers these days. :)   Patch from Bill Paul
+       <wpaul@ctr.columbia.edu>.
+
+       Have Amanda include either readline.h or readline/readline.h
+       Fix suggested by Neal Becker <neal@ctd.comsat.com>.
+
+       Have --with-includes put the -I flags into $CPPFLAGS and
+       $CFLAGS so that AC_CHECK_HEADERS will find other include
+       files.  Problem noted by Neal Becker <neal@ctd.comsat.com>.
+
+       Fixed common-src/Makefile.am to put the extra libamanda.a
+       sources into the EXTRA_libamanda_a_SOURCES variable instead of
+       EXTRA_DIST.  Fix from Tom Tromey <tromey@drip.Colorado.EDU>.
+
+       When compiling amgetidx.c with some compilers, trigraph
+       substitutions were being made when they should not have been.
+       Protect the code from this.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Test for flock support in the following order:
+               1) POSIX fcntl file locking
+               2) flock locking
+               3) lockf locking
+       The common-src/flock.c file will only be used if the lockf type
+       locking is needed on this system.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Have Samba support compile in only if requested by the user.
+       Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Configure was not using $CFLAGS and $CPPFLAGS when trying to
+       calculate the select argument type.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Updated amanda.h to include alloca.h if the system has it and
+       if it's ok to include.  Also protect more include files with
+       #ifdefs found by configure.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Linux does not use the raw device names to do backups.
+       configure now checks to see if it can find a raw disk device
+       file whose name is built from root's mount point.  If it can't,
+       then set RDEV_PREFIX to use /dev/ instead of /dev/r.  Fix
+       suggested by Brian <brian.s.mogged@uwrf.edu> and Ken Latta
+       <latta@parc.xerox.com>.
+
+       Fixed const cast message from regex.c.  Problem noted by Ken
+       Laprade <klaprade@harris.com>.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Configure was not checking for the OSF1_VDUMP #ifdef used in
+       Amanda.  It now will set OSF1_VDUMP if vdump is found on the
+       system.  However, it does not check if the system is really a
+       OSF system.  Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Have configure check for asm/byteorder.h for
+       sparc-unknown-linux-gnu.  Problem noted by Eric Doutreleau
+       <ed@cti.ecp.fr>.
+
+       Remove the check for libintl.h from configure.  It was only
+       being used for regex.c, which really didn't need it.  Patch
+       from Blair Zajac <blair@gps.caltech.edu>.
+
+       Convert all code to K&R C by trying to compile Amanda using
+       /usr/bin/cc on a SunOS 4.1.1 machine.  Have configure check if
+       the compiler can handle the volatile keyword and if it can't,
+       #define it to empty in the config.h file.  Patch from Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Move the contents of versuff.h into version.h and remove
+       versuff.h.  Add a new function called version() which returns
+       the version string.  Use version() in some of the programs.
+       Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       m88k-motorola-sysv4 systems define L_FAIL, which is used by
+       logfile.h.  Undefine it in logfile.h.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Include amindex-1.0 from Alan McIvor.  It includes these
+       improvements over 0.3:
+               Amrecover now provides the ability to restore files
+               from the tapes, via the "extract" command.
+
+               Support for gnutar based index generation (but not file
+               restoration yet).
+
+               Numerous bug fixes.
+
+       Have amgetidx try to open a socket to the shell/tcp port on the
+       remote machine and cache if it succeeds.  If it connection
+       attempt succeeds, then attempt to get the index files over from
+       the client.  Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Update patch-system to include the amidxtape service at
+       10083/tcp.  Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Configure said that the server configuration was OK and then
+       next said it wasn't.  Remove these checks.  Patch from Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Fixed building Amanda for multiple architectures in
+       subdirectories of Amanda.  Problem noted by Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+
+Version 2.3.0.4b1
+
+       Fix a problem with `amadmin <conf> balance' dumping core.  If
+       some disks are overdue, they are stored in the sequence array
+       with a negative index.  This has the potential to cause memory
+       corruption, and it makes the reported balance figures not add up
+       to the same as the total.  Since overdue disks are really going
+       to be candidated for today's backups, they are thrown in the
+       bin for those.  Patch from Ken Laprade <klaprade@harris.com>.
+
+       Add Samba client support using smbclient to Amanda.  Samba must
+       be patched with the file patches/samba-1.9.16p2.1.patch - this
+       is a patch for 1.9.16p2 of Samba, and modifies the way the
+       'dir' command works, and adds totals to both the dir command
+       and the tar command, via stderr.  These are used by amanda to
+       estimate and count backup sizes.  This should be installed on
+       an amanda 'client' host, that will act as the 'samba server'
+       host.  This will most likely be the same machine as the Amanda
+       master server.  Patches from Michael Zucchi
+       <zucchi@cis.unisa.edu.au>.
+
+       Amrmtape converted from Bash to Bourne shell.  Patch from Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Fix the indexing code to use "arglist.h" instead of <stdarg.h>
+       Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Have amdump call amgetidx and amtrmidx.  Put amgetidx and
+       amtrmidx into the libexec directory instead of the bin
+       directory, since Amanda users will not use these by hand.
+       Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Modified diskfile.c to match hostname in the backup header
+       against the fully qualified domain name in disklist file,
+       because amflush fails in a multidomain backup environment, as
+       backup headers have only the hostname.  Patch from Karl
+       Lehenbauer <karl@neosoft.com>.
+
+       Have autoconf figure out if some functions are not declared and
+       if they are not, then declare them.  Patch from Blair Zajac
+       <blair@gps.caltech.edu>.
+
+       Add security fixes to amandad.c.  It now checks the forward and
+       reverse DNS names for consistency.  Added a configure option
+       --amandahosts to use Michael's code to use .amandahosts instead
+       of .rhosts.  Patch from Michael Douglass <mikedoug@texas.net>.
+
+       Add amverify, a simple shell script to check Amanda tapes -
+       gnutar driven backups only.  Patch from Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+
+       Add the version option to amadmin (eg amadmin <conf> version).
+       Patch from Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Add the current option to amtape (eg amtape <conf> current).
+       This let's you the label of the current tape only without using
+       dd.  Patch from Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Gnutar support for amindex added.  Patch from Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+
+       Calcsize supports exclude-list (gtar).  The source was
+       extracted from gnutar itself to be 100% compatible.  Patch from
+       Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Calcsize checks the file type and ignores special files and
+       pipes.  Patch from Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Calcsizes calculation for gnu tar archives had a bug (gtar file
+       blocks always are a multiple of 2k).  Patch from Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+
+       `amandates.c': amdandad suffered by missing AMANDATES_FILE.
+       Now it creates this file before missing it.  Patch from Thomas
+       Hepper <Thomas.Hepper@icem.de>.
+
+       `createindex-gnutar.c' added.  Patch from Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+
+       alloca(), strdup.c and getcwd added for those system who don't
+       have them.  Patch from Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       A dirty hack for BSD based systems without sigaction(), see
+       amanda.h.  Patch from Thomas Hepper <Thomas.Hepper@icem.de>.
+       Add two scripts, hp-changer and no-changer. hp-changer is a
+       tape changer script for a HP DAT changer. Every 10th tape a
+       taper clean runs.  no-changer is a changer-like script for
+       single tape streamer.  It makes Amanda see a tape changer unit
+       with an infinite count of tapes (and requires an operator to
+       change the tapes :-)). Every 10 tapes the operator is
+       recommended to insert a cleaning tape.  Patch from Thomas
+       Hepper <Thomas.Hepper@icem.de>.
+
+       The version suffix adding is done with a seperate function
+       versionsuffix() also available as standalone program.  Patch
+       from Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Several files got debug support. Patch from Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+
+       Added an idle type file-too-large to driver.c to avoid dumping
+       files to the holding disk(s) which exceed the maximum file size
+       (2 GB on the most 32-bit machines).  Patch from Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+
+       Some minor bug fixes, mostly regarding missing or wrong casts
+       confusing c compilers (shmat()/shmdt(), select()).  Patch from
+       Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Genversion gives some more information.  Patch from Thomas
+       Hepper <Thomas.Hepper@icem.de>.
+
+       getfsent.c and statfs.c have been cleaned up. The have to be
+       checked on non-Irix/Solaris/NextStep/HPUX/AIX/Linux-systems.
+       Patch from Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Simple support if readline.a is missing.  NEVER TESTED!  Patch
+       from Thomas Hepper <Thomas.Hepper@icem.de>.
+
+       Linux requires libdb.a and ndbm.h to handle database files. Not
+       really what I expected.  Patch from Thomas Hepper
+       <Thomas.Hepper@icem.de>.
+       Here's a simple patch which fixes a problem that causes amflush
+       to erroneously complain "ignoring cruft file" about good dump
+       files on the holding disk, and fail to flush them to tape.
+       This happens if your holding disk directory has a long name,
+       and the dump file also has a long name (i.e. if you use
+       filesystem mount points in disklist).  The problem occurs if
+       the holding directory + filename exceeds 80 bytes.  The patch
+       still leaves a length limitation, but at least it matches the
+       size limit imposed by driver (and thus dumper & taper) of 128
+       bytes.  Patch from Marion Hakanson <hakanson@cse.ogi.edu>.
+
+       Use regex.h and regex.c from
+       ftp://prep.ai.mit.edu/sh-utils-1.15.tar.gz instead of the regex
+       checking code in the system.  This code includes re_comp and
+       re_exec calls, so it will work on any system.  Patch by Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Amadmin find reports the wrong tape file numbers after when a
+       dump is amflush'ed to tape.  Patch by Ralf Fassel
+       <ralf@atg.venture.de>.
+
+       Fix a bug where dumps of disks on the Amanda server are counted
+       against the available network bandwidth.  Patch from Marion
+       Hakanson <hakanson@cse.ogi.edu>.
+
+       Tell gnutar to not exit with a nonzero value if a read failed.
+       This prevents backups from aborting if a file disappeared
+       before gnutar could save it.  Patch from Hal Snyder
+       <hal@vailsys.com>.
+
+       Fix dumper which can cause the entire amdump run to hang after
+       dumper issues a "TRY-AGAIN" message to driver while dumping
+       directly to tape.  Patch from Marion Hakanson's
+       <hakanson@cse.ogi.edu>.
+
+       Added Marion Hakanson's <hakanson@cse.ogi.edu> patches to fix
+       problems when amanda dumps directly to tape (i.e. when holding
+       space is full, or you're backing up a huge filesystem, etc.).
+       The bug occurs in the way taper determines it has succeeded
+       when doing a PORT-WRITE operation (i.e. dumping directly to
+       tape).  It used to assume that an EOF meant no more data --
+       true if it's reading from a file, but when reading from a port
+       (i.e. directly from a dump process), an EOF could signal
+       abnormal exit as well as a normal one.  So, I extended the
+       protocol between driver and taper when dumping directly to tape
+       (see dump_to_tape() in driver.c) so the taper will wait for the
+       driver to pass PORT-WRITE-SUCCESS or PORT-WRITE-FAILURE to the
+       taper (since driver gets OK/not-OK from the dumper) before the
+       taper records success or failure.  Note that this change
+       affects only the PORT-WRITE case in taper.  FYI, the bug
+       resulted in the curinfo database for a failed port-dump to have
+       the tape-label & file-number fields updated with the location
+       of the failed dump, even though the timestamp & dump statistics
+       still have the values of the last successful dump (the latter
+       fields are updated by dumper itself).
+
+       Patches from George Scott <George.Scott@cc.monash.edu.au> to
+       fix the following problems in planner.c.
+       1) Initialise total_size, total_lev0 and balanced_size.  They
+       are updated in analyze_estimates() but never initialised.  Zero
+       them before the first call.
+       2) Remove oversize dumps.   If there is a dump whose estimated
+       size is larger than the tape the planner would tend to throw
+       away all the other dumps and then probably generate an
+       unworkable plan anyway.  (The standard 2.2.6 planner probably
+       tossed these dumps fairly quickly for other reasons, but my
+       next fix made this one almost mandatory!)  The fix is to drop
+       these enormous dumps right at the begining.  This shouldn't be
+       triggered for anyone with a sane configuration.
+       3) Promote hills.  There are two ways to create a balanced
+       cycle.  The first is to fill in any holes and the second is to
+       remove any hills.  The original planner is good at doing the
+       first but doesn't even attempt the second.  A quick look at
+       "amadmin balance" would show big hills quite clearly.  This fix
+       effectively does an "amadmin balance" and promotes a dump from
+       one of the "hills".  This type of promotion is quite
+       restricted:
+         - don't bother if we already plan to do any level 0 dumps
+         - don't promote a dump if it was going to be the only level 0
+           to be done on that run (ie, ignore hills that are only one
+           dump high)
+         - only promote one level 0 by this method
+         - don't exceed tape_length
+       The key to it is the first restriction.  Large sites (with
+       large numbers of disks and a large balanced_size) will have at
+       least one level 0 scheduled for each day in the dump cycle and
+       will already have a balanced cycle.  This code will not
+       activate for them.  Small sites will probably not have a level
+       0 scheduled and will benefit.  The second restriction will stop
+       Amanda from constantly promoting dumps when the schedule is as
+       balanced as it will go.  The third restriction will stop Amanda
+       over reacting.  Promoting one dump by this method would take
+       total_lev0 larger that balanced_size.  If it wouldn't then the
+       first stage promotion didn't work like it should.
+       4) Initialise got_estimate for all cases.  This fix was from
+       der Mouse <mouse@collatz.mcrcim.mcgill.edu>.  "got_estimate"
+       wasn't being initialised for skipped disks.  Later in the code
+       it was being used in all cases.  The fix is to move its
+       initialisation up a few lines.
+       5) Explicitly ignore off-line disks.  If a disk is off-line
+       when the planner is run it gets -1 for all dump sizes.  These
+       were ignored at a later stage.  This fix explicitly ignores
+       them up front.
+       6) Ignore down machines.  If a machine is down when the planner
+       is run it guesses from historical data what the size of
+       tonights dump is likely to be and schedules a dump anyway.  The
+       dumper then usually discovers that the machine is still down
+       and ends up with a half full tape.  Unfortunately the planner
+       had to delay another dump because it thought that the tape was
+       full.  The fix here is for the planner to discard unavailable
+       machines totally rather than just ignore the fact that they are
+       unavailable.
+       7) Keep at least one total.  Amanda moves level 0 dumps back to
+       incrementals to try and fit everything onto the tape.
+       Unfortunately if all your incrementals are too big (or your
+       tape too small) it can move all of your level 0 dumps.  This
+       ends up being a kind of deadlock since, unless a level 0 gets
+       done, the incrementals will not reduce in size and until the
+       incrementals reduce in size there will not be enough room to
+       fit in a level 0.  (This is not quite accurate since a level 4
+       dump can get bumped to a level 5 which reduces its size.
+       However, this deadlock has happened to me and for many days in
+       a row.)  The fix is to pick on the highest priority level 0 and
+       not let it be moved.  This change will not affect users with
+       reasonably sized tapes since Amanda would not have moved all
+       their disks to incrementals.
+       8) Make usage of total_lev0 consistent.  "total_lev0" is a
+       double and doesn't include tape_mark's.  Make it so.
+
+       Add a fflush(outf) to amcheck.c.  Patch from Mike Russell
+       <Michael_Russell@Brown.EDU>.
+
+       Fix problems with amhpfixdevs.  Patch from Michael Schmitz
+       <mschmitz@iname.com>.
+
+       Have DEC OSF1 use installbsd instead of install.  Patch from
+       Rainer Landes <rlandes@fphws01.physik.uni-karlsruhe.de>.
+
+       Have amcontrol take the first command line argument as the
+       configuration to use.  If there are no command line arguments,
+       then use daily.  Patch from Thomas Schmeidl
+       <schmeidl@nwp.kwu.siemens.de>.
+
+       Removed --atime-preserve from sendbackup-gnutar.c so that
+       incremental backups of filesystems will work.  Patch from
+       Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+       Change all #if __STDC__ to #ifdef __STDC__ for those systems
+       that define __STDC__ to 0, such as Solaris using cc -Xt, cc
+       -Xa.  Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Increase the socket buffer size, and set a low watter mark at
+       32k.  This cut the number of syscalls done to process one 32k
+       block from dozens down to 4 (select, read, lseek, write).
+       Patch from Brad Huntting <huntting@glarp.com>.
+
+       Include amindex-0.3 from Alan McIvor <alan@salan.auck.irl.cri.nz>.
+
+       Add the "srvcompress" option to compress dumps on the tape host
+       instead of on the client machines.  This may be useful when a
+       fast tape host is backing up slow clients.  The patches add a
+       dump-type option, analogous to "compress-fast" or
+       "compress-best" - the way to use it is to create a new dumptype
+       in your amanda.conf that includes "srvcompress" and use the new
+       dumptype for those filesystems you wish to have compressed on
+       the tape server. For example, in amanda.conf:
+           define dumptype srvcomp-user {
+           comment "Partitions on slow machines, compressed on tapehost"
+           options srvcompress
+           priority medium
+       }
+       Patches from Eric Volpe <epv@panix.com>.
+
+       Increase the planner timeout for one estimate from 30 seconds
+       to 120 seconds.  Patch from Michael Schmitz
+       <mschmitz@iname.com>.
+
+       The select(2) prototype on HPUX specifies 'int' as argument
+       type of the filedescriptor arguments. All other systems I know
+       of use 'fd_set'. This has been fixed by having configure check
+       the argument type to select and adding casts to the select(2)
+       calls.  Patch from Michael Schmitz  <mschmitz@iname.com>.
+
+       Improve the diagnostic output and increase the robustness of
+       the system by adding better error checking on communication
+       between taper & driver, and among the two taper processes.
+       Patches from Marion Hakanson <hakanson@cse.ogi.edu>.
+
+       Convert all flock() calls to use POSIX-style locks via the
+       fcntl(2) call.  This operation was prompted by the fact that
+       the flock() emulation in the Amanda-provided common-src/flock.c
+       was broken for read-only file descriptors, and the fcntl(2)
+       locks are widely available.  This patch makes it possible to
+       have a read-only lock on the /etc/amandates file on systems
+       which want to use it.  I've built and tested the patched code
+       on Amanda servers running on Digital Unix v3.2B (on Alpha
+       hardware) and on SPARC Solaris-2.5.1.  It's also been compiled
+       here on SPARC's running SunOS-4.1.3u1b, HP-UX 9.0[345], and
+       NeXTstep-3.3 (NeXT hardware).  Note that the patches also
+       remove all trace of the NEED_FLOCK define, and I have removed
+       the file common-src/flock.c from our source tree here.  Patch
+       from Marion Hakanson <hakanson@cse.ogi.edu>.
+
+       For disk/filesystem names which are wider than 14 characters,
+       have reporter print out the rightmost characters of the disk
+       name, which is usually more meaningful in a daily backup
+       summary.  Patch from Marion Hakanson <hakanson@cse.ogi.edu>.
+
+       Lets amflush work in a wider variety of cases than was
+       previously true (it used to work if the disklist contains only
+       the first token of each hostname).  sendbackup-dump.c and
+       sendbackup-gnutar.c now do not trim the domain name from the
+       host name that is sent back to the server.  amflush now looks
+       for an exact match, in the database.  If it can't find one it
+       strips the last token off the dump header hostname and keeps
+       trying until it finds a match in the disklist or runs out of
+       tokens.  This also has the advantage that if gethostname()
+       returns FQDNs and you specify the same FQDNs in the disklist,
+       then amflush will always work.  It will also work as long as
+       the disklist and gethostname() on the clients return enough
+       information to be unambiguous.  Patch from James Mathiesen
+       <james@deshaw.com>.
+
+       Increase the READ_TIMEOUT in dumper.c to 30 minutes.  This
+       needs to be longer than the longest amount of time dump will
+       not produce output.  People have observed dumps taking more
+       than 10 minutes to finish mapping some of the passes
+       sometimes.  Patch from James Mathiesen <james@deshaw.com>.
+       
+       Added Adrian T. Filipi-Martin's <atf3r@cs.virginia.edu>
+       amrmtape script, which allows you to invalidate the contents of
+       an existing backup tape within the Amanda current tape
+       database.  This is meant as a recovery mecanism for when a good
+       backup is damaged either by faulty hardware or user error,
+       i.e.  the tape is eaten by the tape drive, or the tape has been
+       overwritten.  Blair Zajac wrote a quick little manual page for
+       this script.
+
+       amrmtape was using the return value from amadmin and amadmin
+       was exiting with a non-zero value, causing amrmtape to quit.
+       Added a return 0 statement to amadmin.c.  Patch from Blair
+       Zajac <blair@gps.caltech.edu>.
+
+       Went through all of the files and changed void main()'s to int
+       main()'s.  Patch from Blair Zajac <blair@gps.caltech.edu>.
+
+       Removed the 50 tape file limit in amcleanup and amdump.
+
+       createindex-dump and sendbackup-dump did not always take into
+       account the version suffix.  This is now handled.  Patch from
+       Philippe Charnier <charnier@lirmm.fr>
+
+       Compile and install amrecover and amrestore as client programs,
+       not a server program.  The motovation for this is that
+       amrecover is truly a program for all of the users on the
+       system, while the remaining amanda programs could be used by
+       only the system administrator.  Patch from Alexandre Oliva
+       <oliva@dcc.unicamp.br>.
+
+       The program amtrmidx fails to close some of the pipes it uses,
+       and this can lead to failure on systems with large numbers of
+       disks with incomplete database sets, and file descriptor
+       ulimits set.  Patch from Alan McIvor <alan@auck.irl.cri.nz>.
+
+Version 2.3.0.3
+
+       Expanded the width of the DISK column from the reporter
+       output.  I like to use mount points like /export/home?? instead
+       of device names to back up.  Since the width of the disk name
+       field from reporter's output is pretty small, I couldn't easily
+       figure out the statistics for a particular partition.  Patch
+       from Blair Zajac <blair@gps.caltech.edu>.
+
+       Included Eric Doutreleau <ed@cti.ecp.fr> patch's for amadmin to
+       handle multiple tapes better.  The patch that he posted on used
+       a hardwired value of 6 for runtapes, which I changed.
+
+       Included Marion Hakanson's <hakanson@cse.ogi.edu> patches to
+       amadmin.c and amadmin.8 to let amadmin use the same disk
+       regular expression matching as amrestore.  So now "^/$" will
+       match only the root partition, not all of the disks.
+
+       Added a patch from George.Scott@cc.monash.edu.au which makes
+       new disks and forces dump with a higher priority.
+
+       Changed tools/munge to delete blank lines and the commented
+       lines that the C preprocessor generates (i.e. # 123).  We also
+       remove the space after the = sign that can be generated by cpp
+       on some systems.
+
+       Installed amindex-0.2 from Alan McIvor <alan@auck.irl.cri.nz>
+       with the following patches:
+
+               Fix problem so that rsh'ing on a hpux host works.
+               Patch from Neal Becker <neal@ctd.comsat.com>.  This
+               patch includes a new #define for RSH_COMMAND, which is
+               set to rsh in config-common.h and defined as remsh in
+               config.h-hpux.
+
+               Fix bugs in createindex-dump.c when comparing errno to
+               EINTR.  The code was using = instead of ==.  Patch from
+               Neal Becker <neal@ctd.comsat.com>.  I'm guessing this
+               might fix some of the runaway createindex-dump
+               processes that I have seen on my system.
+
+               On my system, we use MAE which likes to generate path
+               names with spaces in them.  I patched
+               createindex-dump.c so that filenames with spaces have
+               the whole filename listed.  Patch from Blair Zajac
+               <blair@gps.caltech.edu>.
+
+               Patch amtrmidx.c so that backups using the mount points
+               for disks instead of the device name have the /'s
+               replaced with _'s.  Patch from Blair Zajac
+               <blair@gps.caltech.edu>.
+
+Version 2.3.0.2
+
+       Changed the signals being sent to xfsdump for Irix so that it
+       will be killed without dumping a core.
+
+       Fixed a typo in the definition of XFSDUMP in config.h-irix.
+
+       Removed the extra option.s-* and copied options.h to
+       options.h-vanilla.
+
+       Moved the amrestore manual page into the man directory so it
+       would get installed.
+
+Version 2.3.0.1
+
+       amindex-0.1 written by Alan McIvor <alan@kauri.auck.irl.cri.nz>
+       installed.  amindex generates an index of all of the files that
+       were dumped.  It is nice to see what files were dumped before
+       you restore a whole bunch of tapes looking for a file.  I
+       patched some of this code.  Here are some of the changes:
+
+               Switched the Imakefile to Makefile and Makefile.in to
+               be more consistent with the system used by the rest of
+               amanda.
+
+               Moved the configuration #defines out of the specific
+               files (such as amrecover.c) into options.h, so that
+               people installing this version of amanda would be able
+               to see the required changes more easily and not have to
+               edit multiple files.
+
+               Made some changes to the codes to remove #include's
+               where amanda.h would include them and also check if the
+               system had the particular include file.
+
+               Added code to set_commands.c and amgetidx.c to change
+               /'s in disk names to _'s.
+
+               Added code to amrecover.c to properly compile on
+               Solaris hosts.
+
+               With the -Xc compiler option on Solaris and with
+               amindex, the sigaction structure was not being
+               declared.  Added -D__EXTENSIONS__ to config.h-sunos5 so
+               that sigaction would be declared.
+
+               I changed a bunch of fprintf to perrors.
+
+       Include Sean Kelly's <kelly@fsl.noaa.gov> patch for tools/munge
+       for FreeBSD-2.1.5.
+
+       Used Peter Lackner's <plo@came.sbg.ac.at> patches for DU 4.0.
+
+       Installed Ken Laprade's <klaprade@harris.com> patches for
+       amanda to handle both EFS and XFs file systems on the same
+       client.  The only change from his patch is to #ifdef XFSDUMP
+       the kill(-dumppid, SIGTERM) so the SIGTERM signal will be used
+       on other systems, while SIGQUIT will be used on Irix systems.
+
+       Installed Marion Hakanson's <hakanson@cse.ogi.edu> patches for
+       the main config file to include subsidiary config files.
+
+       On Solaris, sometimes the hdr->handle variable in amandad.c
+       would be null, causing core dumps when it was used in a sprintf
+       statement.  The code now checks if hdr->handle is null and
+       prints a "" if it is null.  This was only done in amandad.c.
+
+       Fix a problem where new disks would be added but not backed up
+       concurrently.  Changes to diskfile.c.  I forgot who put this
+       patch up on the mailing list.
+
+       I made some changes to options.h to allow the user to more
+       easily install the programs under a different user.  This meant
+       defining two new #defines, MK_AMANDA_USER and
+       MK_QUOTED_AMANDA_USER which are used in the appropriate
+       Makefiles.
+
+       Used Marion Hakanson's <hakanson@cse.ogi.edu> patch for taper.c
+       for multiple tapes.
+
+       Included Joachim Loehr's <Joachim.Loeh@stadt-mh.de>
+       script to automatically figure out which kind of HP-UX file
+       system is being dumped.  Look in tools for the script and a
+       README.
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 76
+End:
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..3b50ea9
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,176 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes a while.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..3600068
--- /dev/null
@@ -0,0 +1,105 @@
+## Process this file with automake to produce Makefile.in
+AUTOMAKE_OPTIONS = 1.4 foreign
+
+ACINCLUDE_M4 = $(srcdir)/acinclude.m4
+ACINCLUDE_M4I = $(srcdir)/config/acinclude.m4i
+LIBTOOL_M4I = $(srcdir)/config/libtool.m4i
+ACINCLUDE_M4_DEPS = $(ACINCLUDE_M4I) $(LIBTOOL_M4I)
+
+if WANT_CLIENT
+CLIENT_SUBDIRS = client-src
+endif
+if WANT_TAPE
+TAPE_SUBDIRS = tape-src
+endif
+if WANT_SERVER
+SERVER_SUBDIRS = server-src changer-src
+endif
+if WANT_RESTORE
+RESTORE_SUBDIRS = restore-src
+endif
+if WANT_RECOVER
+RECOVER_SUBDIRS = recover-src
+endif
+if WANT_AMPLOT
+PLOT_SUBDIRS = amplot
+endif
+# order is significant, don't change it arbitrarily
+SUBDIRS = \
+       config \
+       common-src \
+       $(CLIENT_SUBDIRS) \
+       $(TAPE_SUBDIRS) \
+       $(SERVER_SUBDIRS) \
+       $(RESTORE_SUBDIRS) \
+       $(RECOVER_SUBDIRS) \
+       $(PLOT_SUBDIRS) \
+       man docs example
+
+pkgdata_DATA = \
+       COPYRIGHT                       \
+       COPYRIGHT-APACHE                \
+       COPYRIGHT-REGEX
+
+EXTRA_DIST = $(SNAPSHOT_STAMP) \
+       $(pkgdata_DATA)                 \
+       contrib/README                  \
+       contrib/dbbackup.README         \
+       contrib/dbbackup.ksh            \
+       contrib/dbbackup.sql            \
+       contrib/dbbackup.tcl            \
+       contrib/mkamandisk              \
+       contrib/set_prod_link.pl        \
+       contrib/sst/Makefile            \
+       contrib/sst/README              \
+       contrib/sst/README.Amanda       \
+       contrib/sst/sst.c               \
+       contrib/sst/sst.conf            \
+       contrib/sst/sst_def.h           \
+       contrib/sst/sstest.c            \
+       patches/regex-3.6alpha.patch    \
+       patches/samba-largefs.patch     \
+       patches/tar-1.12.patch          \
+       regex-src/COPYRIGHT             \
+       regex-src/Makefile              \
+       regex-src/README                \
+       regex-src/WHATSNEW              \
+       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/regex.3               \
+       regex-src/regex.7               \
+       regex-src/regex2.h              \
+       regex-src/regexec.c             \
+       regex-src/regfree.c             \
+       regex-src/split.c               \
+       regex-src/tests                 \
+       regex-src/utils.h               \
+       regex-src/fake/limits.h         \
+       regex-src/fake/memmove.c        \
+       regex-src/fake/stdlib.h
+
+$(ACINCLUDE_M4): $(ACINCLUDE_M4_DEPS)
+       @-rm -f $@
+       @cat $(ACINCLUDE_M4_DEPS) > $@
+
+libtool: $(LIBTOOL_DEPS)
+       $(SHELL) ./config.status --recheck
+
+## This is only meaningful for snapshots, but it won't hurt releases.
+CONFIG_STATUS = config.status
+$(CONFIG_STATUS): $(SNAPSHOT_STAMP)
+SNAPSHOT:
+       : SNAPSHOT file was removed, will reconfigure...
+
+## 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.
+
+dist-hook:
+       find $(distdir)/. -name '*.test.c' -exec rm {} \;
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..d6be98a
--- /dev/null
@@ -0,0 +1,780 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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@
+
+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 = :
+host_triplet = @host@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS \
+       ChangeLog INSTALL NEWS
+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)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+       html-recursive info-recursive install-data-recursive \
+       install-exec-recursive install-info-recursive \
+       install-recursive installcheck-recursive installdirs-recursive \
+       pdf-recursive ps-recursive uninstall-info-recursive \
+       uninstall-recursive
+am__installdirs = "$(DESTDIR)$(pkgdatadir)"
+pkgdataDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgdata_DATA)
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = config common-src client-src tape-src server-src \
+       changer-src restore-src recover-src amplot man docs example
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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@
+AUTOMAKE_OPTIONS = 1.4 foreign
+ACINCLUDE_M4 = $(srcdir)/acinclude.m4
+ACINCLUDE_M4I = $(srcdir)/config/acinclude.m4i
+LIBTOOL_M4I = $(srcdir)/config/libtool.m4i
+ACINCLUDE_M4_DEPS = $(ACINCLUDE_M4I) $(LIBTOOL_M4I)
+@WANT_CLIENT_TRUE@CLIENT_SUBDIRS = client-src
+@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_AMPLOT_TRUE@PLOT_SUBDIRS = amplot
+# order is significant, don't change it arbitrarily
+SUBDIRS = \
+       config \
+       common-src \
+       $(CLIENT_SUBDIRS) \
+       $(TAPE_SUBDIRS) \
+       $(SERVER_SUBDIRS) \
+       $(RESTORE_SUBDIRS) \
+       $(RECOVER_SUBDIRS) \
+       $(PLOT_SUBDIRS) \
+       man docs example
+
+pkgdata_DATA = \
+       COPYRIGHT                       \
+       COPYRIGHT-APACHE                \
+       COPYRIGHT-REGEX
+
+EXTRA_DIST = $(SNAPSHOT_STAMP) \
+       $(pkgdata_DATA)                 \
+       contrib/README                  \
+       contrib/dbbackup.README         \
+       contrib/dbbackup.ksh            \
+       contrib/dbbackup.sql            \
+       contrib/dbbackup.tcl            \
+       contrib/mkamandisk              \
+       contrib/set_prod_link.pl        \
+       contrib/sst/Makefile            \
+       contrib/sst/README              \
+       contrib/sst/README.Amanda       \
+       contrib/sst/sst.c               \
+       contrib/sst/sst.conf            \
+       contrib/sst/sst_def.h           \
+       contrib/sst/sstest.c            \
+       patches/regex-3.6alpha.patch    \
+       patches/samba-largefs.patch     \
+       patches/tar-1.12.patch          \
+       regex-src/COPYRIGHT             \
+       regex-src/Makefile              \
+       regex-src/README                \
+       regex-src/WHATSNEW              \
+       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/regex.3               \
+       regex-src/regex.7               \
+       regex-src/regex2.h              \
+       regex-src/regexec.c             \
+       regex-src/regfree.c             \
+       regex-src/split.c               \
+       regex-src/tests                 \
+       regex-src/utils.h               \
+       regex-src/fake/limits.h         \
+       regex-src/fake/memmove.c        \
+       regex-src/fake/stdlib.h
+
+CONFIG_STATUS = config.status
+all: all-recursive
+
+.SUFFIXES:
+am--refresh:
+       @:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
+             cd $(srcdir) && $(AUTOMAKE) --foreign  \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --foreign  Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           echo ' $(SHELL) ./config.status'; \
+           $(SHELL) ./config.status;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+install-pkgdataDATA: $(pkgdata_DATA)
+       @$(NORMAL_INSTALL)
+       test -z "$(pkgdatadir)" || $(mkdir_p) "$(DESTDIR)$(pkgdatadir)"
+       @list='$(pkgdata_DATA)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+         $(pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \
+       done
+
+uninstall-pkgdataDATA:
+       @$(NORMAL_UNINSTALL)
+       @list='$(pkgdata_DATA)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+         rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \
+       done
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+ctags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+       done
+
+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: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+         include_option=--etags-include; \
+         empty_fix=.; \
+       else \
+         include_option=--include; \
+         empty_fix=; \
+       fi; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && \
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
+       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 -z "$$unique" && unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(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)
+       $(am__remove_distdir)
+       mkdir $(distdir)
+       $(mkdir_p) $(distdir)/amplot $(distdir)/changer-src $(distdir)/client-src $(distdir)/common-src $(distdir)/contrib $(distdir)/contrib/sst $(distdir)/example $(distdir)/man $(distdir)/patches $(distdir)/regex-src $(distdir)/regex-src/fake $(distdir)/server-src
+       @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
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d "$(distdir)/$$subdir" \
+           || mkdir "$(distdir)/$$subdir" \
+           || exit 1; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="../$(top_distdir)" \
+               distdir="../$(distdir)/$$subdir" \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
+       $(MAKE) $(AM_MAKEFLAGS) \
+         top_distdir="$(top_distdir)" distdir="$(distdir)" \
+         dist-hook
+       -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+         ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+       || chmod -R a+r $(distdir)
+dist-gzip: distdir
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+
+dist-bzip2: distdir
+       $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2
+       $(am__remove_distdir)
+
+dist-tarZ: distdir
+       $(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z
+       $(am__remove_distdir)
+
+dist-shar: distdir
+       shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+       $(am__remove_distdir)
+
+dist-zip: distdir
+       -rm -f $(distdir).zip
+       zip -rq $(distdir).zip $(distdir)
+       $(am__remove_distdir)
+
+dist dist-all: distdir
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       case '$(DIST_ARCHIVES)' in \
+       *.tar.gz*) \
+         GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\
+       *.tar.bz2*) \
+         bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\
+       *.tar.Z*) \
+         uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
+       *.shar.gz*) \
+         GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+       *.zip*) \
+         unzip $(distdir).zip ;;\
+       esac
+       chmod -R a-w $(distdir); chmod a+w $(distdir)
+       mkdir $(distdir)/_build
+       mkdir $(distdir)/_inst
+       chmod a-w $(distdir)
+       dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+         && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+         && cd $(distdir)/_build \
+         && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+           $(DISTCHECK_CONFIGURE_FLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+         && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+               distuninstallcheck \
+         && chmod -R a-w "$$dc_install_base" \
+         && ({ \
+              (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+                   distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+             } || { rm -rf "$$dc_destdir"; exit 1; }) \
+         && rm -rf "$$dc_destdir" \
+         && $(MAKE) $(AM_MAKEFLAGS) dist \
+         && rm -rf $(DIST_ARCHIVES) \
+         && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+       $(am__remove_distdir)
+       @(echo "$(distdir) archives ready for distribution: "; \
+         list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+         sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+       @cd $(distuninstallcheck_dir) \
+       && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+          || { echo "ERROR: files left after uninstall:" ; \
+               if test -n "$(DESTDIR)"; then \
+                 echo "  (check DESTDIR support)"; \
+               fi ; \
+               $(distuninstallcheck_listfiles) ; \
+               exit 1; } >&2
+distcleancheck: distclean
+       @if test '$(srcdir)' = . ; then \
+         echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+         exit 1 ; \
+       fi
+       @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+         || { echo "ERROR: files left in build directory after distclean:" ; \
+              $(distcleancheck_listfiles) ; \
+              exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+       for dir in "$(DESTDIR)$(pkgdatadir)"; do \
+         test -z "$$dir" || $(mkdir_p) "$$dir"; \
+       done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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:
+       -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-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+       distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pkgdataDATA
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf $(top_srcdir)/autom4te.cache
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-pkgdataDATA
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+       check-am clean clean-generic clean-libtool clean-recursive \
+       ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
+       dist-shar dist-tarZ dist-zip distcheck distclean \
+       distclean-generic distclean-libtool distclean-recursive \
+       distclean-tags distcleancheck distdir distuninstallcheck dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-exec install-exec-am \
+       install-info install-info-am install-man install-pkgdataDATA \
+       install-strip installcheck installcheck-am installdirs \
+       installdirs-am maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-generic \
+       mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \
+       tags tags-recursive uninstall uninstall-am uninstall-info-am \
+       uninstall-pkgdataDATA
+
+
+$(ACINCLUDE_M4): $(ACINCLUDE_M4_DEPS)
+       @-rm -f $@
+       @cat $(ACINCLUDE_M4_DEPS) > $@
+
+libtool: $(LIBTOOL_DEPS)
+       $(SHELL) ./config.status --recheck
+$(CONFIG_STATUS): $(SNAPSHOT_STAMP)
+SNAPSHOT:
+       : SNAPSHOT file was removed, will reconfigure...
+
+dist-hook:
+       find $(distdir)/. -name '*.test.c' -exec rm {} \;
+# 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/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..d2e98ef
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,373 @@
+Changes in release 2.4.4p3
+
+* new chg-iomega changer script.
+* amanda will not use a tape if it's label is not in the tapelist file
+  (eg. after an amrmtape).
+
+Changes in release 2.4.4p2
+
+* new initial_poll_delay config in chg-zd-mtx
+* 'amadmin find' list disk removed from the disklist.
+* amrecover can recover a disk removed from the disklist file.
+* amanda works with samba3.
+* new chg-disk changer script to use with the file: driver.
+* Kerberos 4 support integrated and functional again.
+
+Changes in release 2.4.4p1
+
+* amverify do not advance to next tape at the end.
+* new amflush -b and -s options, change -f behavior.
+* new chg-mcutil changer.
+* amrecover_changer works with chg-multi.
+* default driveslot for chg-zd-mtx is now 0.
+* amplot generate color postscript by default.
+* amplot -b flag to generate b/w postscript.
+* rait: works with file:
+* print a postscript label for each tape used.
+
+Changes in release 2.4.4
+
+* New -a option to amcheck to always send an email.
+
+Changes in release 2.4.4b1
+
+* maxpromoteday: New option for a dumptype.
+* New amtapetype program (replace tapetype)
+* Client compile on CYGWIN
+* amrestore -f <fileno> : amrestore can do fsf before reading the tape
+* amrestore -l <label>  : amrestore can check the label before restoring.
+* New config options:
+  amrecover_do_fsf: Amrecover will use the -f flag of amrestore to position the
+                    tape.
+  amrecover_check_label: amrecover will pass the -l flag to amrestore.
+  amrecover_changer: amrecover will use your changer.
+  maxdumpsize: The maximum size of the dumps during a run,
+               default to tapesize * runtapes
+  taperalgo: select your algo for the taper, try 'largestfit', it can improve
+             tape usage.
+* amrecover allow to retry a skip a tape.
+* New --days option to 'amadmin <config> balance' command.
+* New --date option to amstatus
+* amreport print an usage by tape.
+* Newer promote algorithm that try to reduce the number of full on a
+  single host in a run.
+* New changer: chg-juke, chg-null and chg-rait
+
+Changes in release 2.4.3
+
+* Few small bug fixed
+* New runtapes argument to amverify.
+* New amverifyrun program.
+* 2.4.3 client works with older server.
+
+Changes in release 2.4.3b4
+
+* new noop packet type. It allow the server to know the client features.
+* exclude list with relative path is working again.
+* amstatus is working again.
+
+Changes in release 2.4.3b3
+
+* --with-maxtapeblocksize configure options
+* blocksize tapetype option
+* file-pad tapetype option
+* Multiple exclude in dumptype
+* Option include in dumptype
+* New disklist syntax:
+*   hostname diskname [ diskdevice ] dumptype [ spindle [ interface ] ]
+* chg-zd-mtx: Major cleanup and general overhaul.
+* amrecover: new listdisk command.
+
+Changes in release 2.4.3b2
+
+* amrestore try to find the next chunk in the current directory.
+* amrecover: You can change the tape device between each tape.
+* amstatus work with amflush.
+
+Changes in release 2.4.3b1
+
+* tapeio.
+* New [host [disk]*]* arguments to amdump, amcheck, amadmin and amflush.
+* New [-D datastamp]* arguments to amflush.
+* amrecover: cd accept shell wildcard, new command cdx accept regex.
+* new autoflush option.
+* new dumperstr option to specify the priority order of each dumper.
+
+Changes in release 2.4.2p2
+
+* Mostly bug fixes.
+* Samba passwords are now sent to smbclient via a pipe and never displayed.
+* Amrecover should now work with xfsrestore.
+* Amrecover no longer binds an incorrect port that resulted in connection
+  failures on some systems.
+* Debug files in /tmp/amanda (--with-debug-dir) are now timestamped and old
+  ones automatically cleaned out.  This means more space (a few KBytes) will
+  be used since in a given run, several of the programs are called more than
+  once.  But it also means important debugging information should no longer
+  be lost by the file being overwritten.  The length of time to keep the
+  files is controlled by --with-debug-days (default: 4).  The old flag
+  --with-pid-debug-files is no longer needed and is ignored.
+* updated chg-zd-mtx.sh.in changer.
+
+Changes in release 2.4.2p1
+
+* Bugs fix release, the most annoying one is that amanda could retry
+  the same filesystem indefinitely if it is larger than the holding
+  disk but the estimate was smaller.
+
+Changes in release 2.4.2
+
+* dumptypes can be specialized in the disklist file
+* Amanda will never use more space than specified (use) for an holding
+  disk
+* A dump on holding disk can spread multiple holding disks
+* negative chunksize is no longer supported
+* chunksize is now 1 Gb by default
+* ufsdump -S is now supported on Solaris
+* Samba 2.0.0 is now supported
+* New `incronly' strategy, similar to skip-full, but allows manual
+  scheduling of full backups
+* chg-scsi was ported to several platforms
+* --with-amandahosts is now enabled by default
+* new force-bump, force-no-bump and unforce-bump command in amadmin.
+* Increased the maximum number of filesystems that can be backed up
+  from a single host, by increasing the maximum UDP request packet
+  size
+* A new `dtimeout' keyword in amanda.conf to replace the READ_TIMEOUT
+  constant in dumper.c.
+* A new `ctimeout' keyword in amanda.conf to replace the CHECK_TIMEOUT
+  constant in amcheck.c.
+* new amtrmlog command
+* --with-samba-user is deprecated, the username go in the amandapass file
+
+Changes in release 2.4.1
+
+* FAQ for new users, in docs/FAQ.
+* A new `runspercycle' keyword in amanda.conf to specify the number
+  of amdump runs in a dumpcycle. The default is one run every day.
+  A value of 0 (the default) 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 tape used in the last dumpcycle days / runtapes.
+  If you don't run amdump every days, you must set runspercycle
+  otherwise amanda will noy be able to balance the dump. You must
+  set runspercycle to -1 if you want the same behavior as previous
+  version of amanda.
+* Space to be use as holding disk can now be "use all space except ??? Kb"
+  using a negative value for the 'use' parameter.
+* amrecover will restore SAMBA backups using SAMBA.
+* New `amstatus' program.
+* New `chg-scsi' tape changer program, that replaces `chg-chio' and uses
+  tape-changer-related ioctls on OSs that support them.
+* Reporter can now print tape labels.
+* ZFTAPEs are now supported on Linux.
+* amrestore now accepts a list of filesystems to be restored.
+* New `clean' amtape command.
+* amlabel will only overwrite an Amanda tape if `-f' is specified.
+* Tapes can now be marked so as not to be recycled with amadmin no-reuse.
+* amidxtrm will no longer remove index files of backups in active tapes.
+* Large dumps can now be split into multiple files on holding disk
+  (but they won't span across tapes yet).
+* A total estimate time-out may be specified.
+* Fixed skip-incr and skip-full support.
+* amcheck now accepts -Maddress to send e-mail to the specified address.
+* amdump, amflush and amcheck will use the log files as locks, so as
+  to avoid running concurrently.
+* driver now supports configurable level-0 dumps in degraded mode via
+  new amanda.conf keyword "reserve"; see docs/WHATS.NEW for details.
+* Configure now looks for vxdump and vxrestore in /usr/lib/fs/vxfs for Solaris
+  systems and will use it vxdump/vxrestore automatically on vxfs filesystems.
+* New `killpgrp' setuid-root program, that kills estimate dumps even
+  if they are setuid-root.
+
+Changes in release 2.4.0p1
+
+* Fixed kerberos encryption
+* New --with-owner configure option, to specify owner of installed files
+* amcheck now checks for the existence of gnutar-listdir and of a
+  compressor on the server (for indexes and server compression)
+* Implemented dumptype option `strategy skip'
+* Updated to libtool 1.2a
+* Minor portability-related bugfixes.
+
+Changes in release 2.4.0
+
+* Several security-related fixes, see docs/SECURITY for details.
+* New configuration file syntax: dumptypes can now be used as keywords.
+* New text database format, to replace dbm/ndbm/gdbm/db databases with
+  a more portable and user-friendly format.
+* Index files are now sent through a separate TCP connection, as they
+  are generated, instead of being stored in /tmp.  This breaks Amanda
+  protocol backward compatibility.
+* Estimates are now performed concurrently, if maxdumps>1.
+* At configure time, it is now possible to specify a suffix for amanda
+  service names (--with-testing=suffix) and a directory for debugging
+  files (--with-debugging=/directory/name)
+* New tape changer configuration keywords, that partially standardize
+  tape changer script configuration interface.
+* amrecover can now handle GNU tar and AIX dump restores; it must now
+  be run as root.
+* Shared libraries are built by default, using GNU libtool.
+* Extended regular expression syntax has been adopted.
+* amcheck will no longer report failures about unused programs.
+* It is now possible to specify a SAMBA username at configure time.
+* BSD security is now enabled by default.
+* A time-out for estimate requests can now be specified in amanda.conf.
+* New patch-system script, for editing /etc/services and /etc/inetd.conf.
+* Amdump will wait if a file named `hold' exists in the log directory.
+* Various bugfixes and new ports.
+
+Changes in release 2.3.0.4
+* New chg-generic.conf option 'multieject' added which lets
+  chg-generic work on tape drives that need multiple 'mt offline'
+  commands.  See examples/chg-generic.conf for more information.
+* New configure options:
+  --with-db=DBLIB         Force database library choice from {db,dbm,gdbm,ndbm}
+  --enable-buffered-dump   Use buffered sockets on server for faster dumps
+  --with-group=GROUPNAME   Install all files into group GROUPNAME
+* Include the file seagate-changer.c which controls
+  Seagate/Conner/Archive autoloading DAT drive on NetBSD systems.
+* Add a new amanda.conf option named "starttime" which is used in the
+  dumptype configuration.  It takes one argument which is a time of day
+  (local timezone) formated as either hhmm or hmm (no `.'s, no `:'s,
+  just an integer).  This tells Amanda to start a particular dump at
+  the given time.
+* Index files are now retrieved from the clients through amandad, not rsh/rcp.
+* Fix configure bug when multiple invocations would not do the correct things.
+* Better fully qualified domain name support.
+* Many little dumper fixes.
+* Remove C style comments from amrmtape and fix a bug when there is
+  only one tape in the tapelist.
+* More declarations of Unix system functions for those OSes that do not
+  have declarations.
+* Fix --with-mmap configure bug.
+
+Changes in release 2.3.0.4b3
+* Include amplot-2.2.6 which makes plots of the amdump files for performance
+  improvements.  Amplot requires gnuplot and a version of awk that
+  understands command line variable assignment.
+* Include amoverview which creates a list of each disk dumped and the level
+  and success or failure of those dumps over a complete tapecycle.
+* Amanda now supports backups of clients in different domains.  Requires
+  using the configure --with-fqdn options and fully qualified domain
+  names (FQDNs) in the disklist file.
+* rth-changer checks all system calls for valid returns.
+* no-changer and hp-changer use different status files and do more checking.
+* amrestore works again with gzip compressed tapes.
+* New setuid program rundump for systems where dump must run as root.
+* Setuid programs are now installed o-rwx for tighter security.
+* Fix bug where if Amanda was not configured using the --with-bsd-security
+  configure option, Amanda would not connect to the client machines.  This
+  is now fixed.
+* Rundump and runtar now check if the proper user is invoking them.
+* Amanda now can use gdbm if the compatibility header files are not installed.
+* Bug fixes for gnutar file exclusions.
+* Fix bug in sendsize which would loop forever if debugging was not turned on.
+* Bug fixes in Samba code.
+* More configure and bug fixes for HP-UX, m88k-motorola-sysv4, SGI, OSF, and
+  Ultrix systems.
+
+Changes in release 2.3.0.4b2
+* New tape changer script (rth-changer) for the Robotic Tape Handling system.
+* Include amindex-1.0 from Alan McIvor.
+* Gnutar incrementals should now work.
+* amgetidx now caches if a remote client is reachable.
+* amanda.conf settings used before --with-dbdir and --with-logdir settings
+  in various scripts.
+* New configure options:
+  --with-mmap                          force mmap() instead of shared memory
+  --with-gnutar-listed-incremental=DIR gnutar directory lists go in DIR
+  --enable-gnutar-atime-preserve       gnutar preserves atime, do not use
+  --with-pid-debug-files               use pid in /tmp debugging filenames
+* Samba support must now be explicitly included using --with-smblcient.
+* Amanda now compiles with K&R compilers.
+* Better AIX, Linux, OSF support.
+* configure checks if /dev/r devices exist or not.
+* Amanda uses POSIX fcntl locking before flock or lockf locking if available.
+* dumper.c uses less aggressive I/O values for SunOS server support.
+* Many bug fixes in the configure script for various platforms.
+* Many bug fixes to codes.
+
+Changes in release 2.3.0.4b1
+* Configuration now uses configure.  Build environment now uses
+  automake and autoconf.
+* Samba PC client backup support added.
+* New programs and scripts:
+  amrmtape: invalidate the contents of an existing backup tape
+  amverify: check Amanda tapes for gnutar driven backups.
+  hp-changer: script for a HP DAT changer.
+  no-changer: make a single tape appear like an infinite count tape stacker.
+* New options added to programs:
+  amadmin: `amadmin <conf> version' shows version information.
+  amtape: `amtape <conf> current' shows the current tape label,
+* Amanda now supports server side compression of dumps on the tape
+  host.  Use the srvcompress option in amanda.conf.
+* Better gnutar support for indexing.  Amanda now lets you exclude
+  files from the dump.
+* Tape planning improvements.
+* Email reports have better formating for disks with long mount points.
+* Tighter DNS checking added to amandad.
+* More debugging added to several programs.
+* Amdump now calls amgetidx and amtrmidx.
+* Better support for multidomain environments.
+* Contains amindex-0.3 from Alan McIvor.
+* Many bug fixes and compiler warnings handled.
+
+Changes in release 2.3.0.3
+* Amadmin uses regular expression matching to match disks.
+* Expand the column width of the disk names from reporter.
+* Contains amindex-0.2 from Alan McIvor.
+* Many bug fixes.
+
+Changes in release 2.3.0.2
+* Bug fixes.
+
+Changes in release 2.3.0.1
+* Contains amindex-0.1 from Alan McIvor.
+* Bug fixes.
+
+Changes in release 2.3.0 alpha
+* A number of material bugs fixed, including fixes incorporated into
+  John Stoffel's WPI patches to amanda, which he called 2.2.6.5.
+* Backup files larger than 2 GB now supported.  The current limit is
+  2^31 Kbytes (2 terabytes), which should hold us for a few more years
+  (1/2 :-).
+* Support for GNUTAR-based backups.
+* Support for writing to multiple tapes (sequentially) in one run.
+* Support for multiple backups in parallel from the same client host.
+* Records from the curinfo database can be exported and imported
+  to/from a textual format.  This allows fixing a corrupted database by
+  running the text version through a script and reimporting it.
+  Individual records or the entire database can be exported/imported.
+
+Changes in release 2.2.6
+* A number of material bugs fixed.
+* A lot of lint picked in the whole package.
+* The documentation is now reasonably up to date.
+* This version has been locally compiled and at least the client side
+  tested on the following systems:
+       SunOS 4.1.3     IRIX 5.2
+       Solaris 2.3     BSDI BSD/386 1.1
+       Ultrix 4.2      NetBSD 1.0
+       DEC OSF/1 2.0   AIX 3.2
+  I don't have any HP/UX machines locally to try it on, but I've
+  tracked patches submitted by Neal Becker <neal@ctd.comset.com>, so
+  I'm reasonably confident that 2.2.6 shouldn't be far from the mark on
+  that platform.
+
+Changes in release 2.2.5
+* SYSV shared memory no longer required on server side if mmap is
+  available.
+* Supports GZIP compression.
+* Supports use of mount names as well as device names in disk list
+  (eg "/usr" instead of "sd0g").
+* Amanda now thinks in real-time - you may run it several times a day
+  if you wish, and it won't get confused.
+* Supports Kerberos 4 security as well as BSD-style .rhosts, including
+  encrypting files over the net.  The Kerberos support is available as
+  a separate add-on package - see the file KERBEROS.HOW-TO-GET on the
+  ftp site.
+* Improved network protocol - faster startup, no longer dump specific,
+  hooks in place for non-dump clients.
+* Client-side checks in amcheck - can check sanity of all client hosts
+  very quickly.
+* Supports multiple holding disks, and load balances between them.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..66237de
--- /dev/null
+++ b/README
@@ -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.
+
+See the files COPYRIGHT, COPYRIGHT-REGEX and COPYRIGHT-APACHE for
+distribution conditions and official warranty disclaimer.
+
+PLEASE NOTE: THIS SOFTWARE IS BEING MADE AVAILABLE ``AS-IS''. UMD is making
+this work available so that other people can use it.  This software is in
+production use at our home site - the UMCP Department of Computer Science -
+but we make no warranties that it will work for you.  Amanda development is
+unfunded - the development team maintains the code in their spare time.  As a
+result, there is no support available other than users helping each other on
+the Amanda mailing lists.  See below for information on the mailing lists.
+
+
+WHAT IS AMANDA?
+---------------
+
+This is a release of Amanda, the Advanced Maryland Automatic
+Network Disk Archiver.  Amanda is a backup system designed to archive many
+computers on a network to a single large-capacity tape drive.  
+
+Here are some features of Amanda:
+
+  * written in C, freely distributable.
+  * built on top of standard backup software: Unix dump/restore, GNU Tar
+    and others.
+  * will back up multiple machines in parallel to a holding disk, blasting
+    finished dumps one by one to tape as fast as we can write files to
+    tape.  For example, a ~2 Gb 8mm tape on a ~240K/s interface to a host
+    with a large holding disk can be filled by Amanda in under 4 hours. 
+  * does simple tape management: will not overwrite the wrong tape.
+  * supports tape changers via a generic interface.  Easily customizable to
+    any type of tape carousel, robot, or stacker that can be controlled via
+    the unix command line.
+  * supports Kerberos 4 security, including encrypted dumps.  The Kerberos
+    support is available as a separate add-on package, see the file
+    KERBEROS.HOW-TO-GET on the ftp site, and the file docs/KERBEROS in this
+    package, for more details.
+  * for a restore, tells you what tapes you need, and finds the proper
+    backup image on the tape for you.
+  * recovers gracefully from errors, including down or hung machines.
+  * reports results, including all errors in detail, in email.
+  * will dynamically adjust backup schedule to keep within constraints: no
+    more juggling by hand when adding disks and computers to network.
+  * includes a pre-run checker program, that conducts sanity checks on both
+    the tape server host and all the client hosts (in parallel), and will
+    send an e-mail report of any problems that could cause the backups to
+    fail.
+  * can compress dumps before sending or after sending over the net, with
+    either compress or gzip.
+  * can optionally synchronize with external backups, for those large
+    timesharing computers where you want to do full dumps when the system
+    is down in single-user mode (since BSD dump is not reliable on active
+    filesystems): Amanda will still do your daily dumps.
+  * lots of other options; Amanda is very configurable.
+
+
+WHAT ARE THE SYSTEM REQUIREMENTS FOR AMANDA?
+--------------------------------------------
+
+Amanda requires a host that is mostly idle during the time backups are
+done, with a large capacity tape drive (e.g. an EXABYTE, DAT or DLT tape).
+This becomes the "tape server host".  All the computers you are going to dump
+are the "backup client hosts".  The server host can also be a client host.
+
+Amanda works best with one or more large "holding disk" partitions on the
+server host available to it for buffering dumps before writing to tape.
+The holding disk allows Amanda to run backups in parallel to the disk, only
+writing them to tape when the backup is finished.  Note that the holding
+disk is not required: without it Amanda will run backups sequentially to
+the tape drive.  Running it this way kills the great performance, but still
+allows you to take advantage of Amanda's other features.
+
+As a rule of thumb, for best performance the holding disk should be larger
+than the dump output from your largest disk partitions.  For example, if
+you are backing up some full gigabyte disks that compress down to 500 MB,
+then you'll want 500 MB on your holding disk.  On the other hand, if those
+gigabyte drives are partitioned into 500 MB filesystems, they'll probably
+compress down to 250 MB and you'll only need that much on your holding
+disk.  Amanda will perform better with larger holding disks.
+
+Actually, Amanda will still work if you have full dumps that are larger
+than the holding disk: Amanda will send those dumps directly to tape one at
+a time.  If you have many such dumps you will be limited by the dump speed
+of those machines.
+
+Amanda does not yet support single backup images larger than a tape.
+
+
+WHAT SYSTEMS DOES AMANDA RUN ON?
+--------------------------------
+
+Amanda should run on any modern Unix system that supports dump or GNU
+tar, has sockets and inetd, and either system V shared memory, or BSD
+mmap implemented.
+
+In particular, Amanda 2.4.1p1 has been compiled, and the client side tested
+on the following systems:
+       AIX 3.2 and 4.1
+       BSDI BSD/OS 2.1 and 3.1
+       DEC OSF/1 3.2 and 4.0
+       FreeBSD 2.2.5
+       IRIX 5.2 and 6.3
+       GNU/Linux on x86, m68k, alpha, sparc, arm and powerpc
+       NetBSD 1.0
+       Nextstep 3 (*)
+       OpenBSD 2.5 x86, sparc, etc (ports available)
+       SunOS 4.1.x (x >= 1) and 5.[567]
+       Ultrix 4.2
+       HP-UX 9.x and 10.x (x >= 01)
+
+The Amanda 2.4.1p1 server side is known to run on all of the other
+machines except on those marked with an asterisk.
+
+If you know of any system that is not listed here on which amanda
+builds successfully, either client&server or client-only, please
+report to amanda-hackers@amanda.org.
+
+
+WHERE DO I GET AMANDA?
+----------------------
+
+There are several versions of Amanda.  The latest version at the time
+of this writing is available at:
+
+       ftp://ftp.amanda.org/pub/amanda
+
+
+HOW DO I GET AMANDA UP AND RUNNING?
+-----------------------------------
+
+Read the file docs/INSTALL.  There are a variety of steps, from compiling
+Amanda to installing it on the tape server host and the client machines.
+    docs/INSTALL       contains general installation instructions.
+    docs/SYSTEM.NOTES  contains system-specific information.
+    docs/FAQ            contains answers to frequently asked questions.
+    docs/KERBEROS      explains installation under Kerberos 4.
+    docs/TAPE.CHANGERS explains how to customize the changer interface.
+    docs/WHATS.NEW     details new features.
+
+
+WHO DO I TALK TO IF I HAVE A PROBLEM?
+-------------------------------------
+
+Amanda is completely unsupported and made available as-is.  However,
+you may be able to get useful information in the Amanda mailing lists:
+
+==> To join a mailing list, DO NOT, EVER, send mail to that list.  Send
+    mail to <listname>-request@amanda.org, or amanda-lists@amanda.org,
+    with the following line in the body of the message:
+       subscribe <listname> <your-email-address>
+
+
+    amanda-announce
+        The amanda-announce mailing list is for important announcements
+        related to the Amanda Network Backup Manager package, including new
+        versions, contributions, and fixes.  NOTE: the amanda-users list is
+        itself on the amanda-announce distribution, so you only need to
+        subscribe to one of the two lists, not both.
+       To subscribe, send a message to amanda-announce-request@amanda.org.
+
+    amanda-users
+        The amanda-users mailing list is for questions and general discussion
+        about the Amanda Network Backup Manager.  This package and related
+        files are available via anonymous FTP from ftp.amanda.org in the
+        pub/amanda directory.  NOTE: the amanda-users list is itself on the
+        amanda-announce distribution, so you only need to subscribe to one of
+        the two lists, not both.
+       To subscribe, send a message to amanda-users-request@amanda.org.
+
+    amanda-hackers
+        The amanda-hackers mailing list is for discussion of the
+        technical details of the Amanda package, including extensions,
+        ports, bugs, fixes, and alpha testing of new versions.
+       To subscribe, send a message to amanda-hackers-request@amanda.org.
+
+
+Share and Enjoy,
+The Amanda Development Team
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644 (file)
index 0000000..60b9aec
--- /dev/null
@@ -0,0 +1,6955 @@
+dnl Check if the compiler can handle unsigned long constants, ie 2ul.
+AC_DEFUN([AMANDA_C_UNSIGNED_LONG_CONSTANTS],
+    [
+       AC_CACHE_CHECK(
+           [for working unsigned long constants],
+           amanda_cv_c_unsigned_long_constants,
+           [
+               AC_TRY_COMPILE(
+                   [
+                   ],
+                   [
+                       long l = 1ul;
+                   ],
+                   amanda_cv_c_unsigned_long_constants=yes,
+                   amanda_cv_c_unsigned_long_constants=no
+               )
+           ]
+       )
+       if test "$amanda_cv_c_unsigned_long_constants" = yes; then
+           AC_DEFINE(HAVE_UNSIGNED_LONG_CONSTANTS,1,[Define if the compiler support unsigned long constants. ])
+       fi
+    ]
+)
+
+dnl Check for the argument type for shmat() and shmdt()
+AC_DEFUN([AMANDA_FUNC_SHM_ARG_TYPE],
+    [
+       AC_CACHE_CHECK(
+           [for shmdt() argument type],
+           amanda_cv_shmdt_arg_type,
+           [
+               if test "$ac_cv_func_shmget" = yes; then
+                   cat <<EOF >conftest.$ac_ext
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_IPC_H
+# include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+# include <sys/shm.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" void *shmat(int, void *, int);
+#else
+void *shmat();
+#endif
+
+int main()
+{
+    int i;
+    return 0;
+}
+EOF
+                   ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext >/dev/null 2>/dev/null
+                   if test $? = 0; then
+                       amanda_cv_shmdt_arg_type=void
+                   else
+                       amanda_cv_shmdt_arg_type=char
+                   fi
+                   rm -f conftest*
+               else
+                   amanda_cv_shmdt_arg_type=nothing
+               fi
+           ]
+       )
+       AC_DEFINE_UNQUOTED(SHM_ARG_TYPE,$amanda_cv_shmdt_arg_type,[Define to type of shmget() function argument. ])
+    ]
+)
+
+dnl Figure out the select() argument type.
+AC_DEFUN([AMANDA_FUNC_SELECT_ARG_TYPE],
+    [
+       AC_CACHE_CHECK(
+           [for select() argument type],
+           amanda_cv_select_arg_type,
+           [
+               rm -f conftest.c
+               cat <<EOF >conftest.$ac_ext
+#include "confdefs.h"
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#  include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int main()
+{
+#ifdef FD_SET_POINTER
+       (void)select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, 0);
+#else
+       (void)select(0, (int *) 0, (int *) 0, (int *) 0, 0);
+#endif
+       return 0;
+}
+EOF
+
+               dnl Figure out the select argument type by first trying to
+               dnl compile with the fd_set argument.  If the compile fails,
+               dnl then we know to use the int.  If it suceeds, then try to
+               dnl use the int.  If the int fails, then use fd_set.  If
+               dnl both suceeed, then do a line count on the number of
+               dnl lines that the compiler spit out, assuming that the
+               dnl compile outputing more lines had more errors.
+               amanda_cv_select_arg_type=no
+               select_compile="${CC-cc} -c $CFLAGS $CPPFLAGS"
+               $select_compile -DFD_SET_POINTER conftest.$ac_ext 1>conftest.fd_set 2>&1
+               if test $? -ne 0; then
+                   amanda_cv_select_arg_type=int
+               fi
+               if test "$amanda_cv_select_arg_type" = no; then
+                   $select_compile conftest.$ac_ext 1>conftest.int 2>&1
+                   if test $? -ne 0; then
+                       amanda_cv_select_arg_type=fd_set
+                   fi
+               fi
+               if test "$amanda_cv_select_arg_type" = no; then
+                   wc_fdset=`wc -l <conftest.fd_set`
+                   wc_int=`wc -l <conftest.int`
+                   if test "$wc_fdset" -le "$wc_int"; then
+                       amanda_cv_select_arg_type=fd_set
+                   else
+                       amanda_cv_select_arg_type=int
+                   fi
+               fi
+               rm -f conftest*
+           ]
+       )
+       AC_DEFINE_UNQUOTED(SELECT_ARG_TYPE,$amanda_cv_select_arg_type,[Define to type of select arguments. ])
+    ]
+)
+
+dnl Check if setsockopt can use the SO_SNDTIMEO option.
+dnl This defines HAVE_SO_SNDTIMEO if setsockopt works
+dnl with SO_SNDTIMEO.
+AC_DEFUN([AMANDA_FUNC_SETSOCKOPT_SO_SNDTIMEO],
+    [
+       AC_CACHE_CHECK(
+           [for setsockopt SO_SNDTIMEO option],
+           amanda_cv_setsockopt_SO_SNDTIMEO,
+           [
+               AC_TRY_RUN(
+                   [
+#include <sys/types.h>
+#include <sys/socket.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
+
+main() {
+#ifdef SO_SNDTIMEO
+    int sock = socket(AF_INET, SOCK_STREAM, 0);
+    struct timeval timeout;
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+    return (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
+             (void *)&timeout, sizeof(timeout)));
+#else
+    return -1;
+#endif
+}
+                   ],
+                   amanda_cv_setsockopt_SO_SNDTIMEO=yes,
+                   amanda_cv_setsockopt_SO_SNDTIMEO=no,
+                   amanda_cv_setsockopt_SO_SNDTIMEO=no
+               )
+           ]
+       )
+       if test "$amanda_cv_setsockopt_SO_SNDTIMEO" = yes; then
+           AC_DEFINE(HAVE_SO_SNDTIMEO,1,[Define if SO_SNDTIMEO is available. ])
+       fi
+    ]
+)
+
+dnl Find out how {awk,gawk,nawk,mawk} likes to assign variables, if it
+dnl can do so at all.
+AC_DEFUN([AMANDA_PROG_AWK_VAR],
+    [
+       AC_REQUIRE([AC_PROG_AWK])
+       AC_CACHE_CHECK(
+           [for $AWK command line variable assignment],
+           amanda_cv_awk_var_assignment,
+           [
+               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
+           ]
+       )
+       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
+       AC_SUBST(AWK_VAR_ASSIGNMENT_OPT)
+    ]
+)      
+
+dnl Check for the one or two argument version of gettimeofday.
+AC_DEFUN([AMANDA_FUNC_GETTIMEOFDAY_ARGS],
+    [
+       AC_REQUIRE([AC_HEADER_TIME])
+       AC_CACHE_CHECK(
+           [for gettimeofday number of arguments],
+           amanda_cv_gettimeofday_args,
+           [
+               AC_TRY_COMPILE(
+                   [
+#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
+                   ],
+                   [
+                       struct timeval val;
+                       struct timezone zone;
+                       gettimeofday(&val, &zone);
+                   ],
+                   amanda_cv_gettimeofday_args=2,
+                   amanda_cv_gettimeofday_args=1
+               )
+           ]
+       )
+       if test "$amanda_cv_gettimeofday_args" = 2; then
+           AC_DEFINE(HAVE_TWO_ARG_GETTIMEOFDAY,1,[Define if gettimeofday takes two arguments. ])
+       fi
+    ]
+)
+
+
+
+dnl Check if the compiler understands volatile.
+AC_DEFUN([AMANDA_C_VOLATILE],
+    [
+       AC_CACHE_CHECK(
+           [for working volatile],
+           amanda_cv_c_volatile,
+           [
+               AC_TRY_COMPILE(,
+                   [
+                       volatile int aaa = 0;
+                   ],
+                   amanda_cv_c_volatile=yes,
+                   amanda_cv_c_volatile=no
+               )
+           ]
+       )
+       if test $amanda_cv_c_volatile = no; then
+           AC_DEFINE(volatile, [],[Define to empty if the compiler does not support volatile. ])
+       fi
+    ]
+)
+
+
+dnl Check for if pid_t is a long, int, or short.
+AC_DEFUN([AMANDA_TYPE_PID_T],
+    [
+       AC_REQUIRE([AC_TYPE_PID_T])
+       AC_CACHE_CHECK([for pid_t type], amanda_cv_pid_type,
+           [
+               amanda_cv_pid_type=unknown
+               if test "$ac_cv_type_pid_t" = no; then
+                   amanda_cv_pid_type=int
+               fi
+               for TEST_amanda_cv_pid_type in long short int; do
+                   if test $amanda_cv_pid_type = unknown; then
+                       AC_EGREP_CPP(typedef.*${TEST_amanda_cv_pid_type}.*pid_t,
+                           [
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+                           ],
+                       amanda_cv_pid_type=$TEST_amanda_cv_pid_type)
+                   fi
+                   if test $amanda_cv_pid_type = unknown; then
+                       AC_EGREP_CPP(ZZZZ.*${TEST_amanda_cv_pid_type},
+                           [
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+                               ZZZZ pid_t
+                       ],
+                       amanda_cv_pid_type=$TEST_amanda_cv_pid_type)
+                   fi
+               done
+               if test $amanda_cv_pid_type = unknown; then
+                   amanda_cv_pid_type=int
+               fi
+           ]
+       )
+       case $amanda_cv_pid_type in
+           int)        AC_DEFINE_UNQUOTED(PRINTF_PID_T,"%d",[Define to printf formatting string to print a PID. ]) ;;
+           long)       AC_DEFINE_UNQUOTED(PRINTF_PID_T,"%ld") ;;
+           short)      AC_DEFINE_UNQUOTED(PRINTF_PID_T,"%d") ;;
+       esac
+    ]
+)
+
+dnl
+dnl
+dnl ICE_CHECK_DECL (FUNCTION, HEADER-FILE...)
+dnl If FUNCTION is available, define `HAVE_FUNCTION'.  If it is declared
+dnl in one of the headers named in the whitespace-separated list 
+dnl HEADER_FILE, define `HAVE_FUNCTION_DECL` (in all capitals).
+dnl
+AC_DEFUN([ICE_CHECK_DECL],
+[
+ice_have_$1=no
+AC_CHECK_FUNCS($1, ice_have_$1=yes)
+if test "${ice_have_$1}" = yes; then
+AC_MSG_CHECKING(for $1 declaration in $2)
+AC_CACHE_VAL(ice_cv_have_$1_decl,
+[
+ice_cv_have_$1_decl=no
+changequote(,)dnl
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+changequote([,])dnl
+for header in $2; do
+# Check for ordinary declaration
+AC_EGREP_HEADER([${ice_re_word}$1[     ]*\(], $header, 
+       ice_cv_have_$1_decl=yes)
+if test "$ice_cv_have_$1_decl" = yes; then
+       break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+AC_EGREP_HEADER([${ice_re_word}$1[     ]*$ice_re_params\(\(], $header, 
+       ice_cv_have_$1_decl=yes)
+if test "$ice_cv_have_$1_decl" = yes; then
+       break
+fi
+done
+])
+AC_MSG_RESULT($ice_cv_have_$1_decl)
+if test "$ice_cv_have_$1_decl" = yes; then
+AC_DEFINE_UNQUOTED([HAVE_]translit($1,[a-z],[A-Z])[_DECL],1,[Define if $1 is declared. ])
+fi
+fi
+])dnl
+dnl Test for the presence of <sys/wait.h>, 'union wait', arg-type of 'wait()'.
+dnl by T.E.Dickey" , Jim Spath <jspath@mail.bcpl.lib.md.us>
+dnl
+dnl     FIXME: These tests should have been in autoconf 1.11!
+dnl
+dnl     Note that we cannot simply grep for 'union wait' in the wait.h file,
+dnl     because some Posix systems turn this on only when a BSD variable is
+dnl     defined. Since I'm trying to do without special defines, I'll live
+dnl     with the default behavior of the include-file.
+dnl
+dnl     I do _2_ compile checks, because we may have union-wait, but the
+dnl     prototype for 'wait()' may want an int.
+dnl
+dnl     Don't use HAVE_UNION_WAIT, because the autoconf documentation implies
+dnl     that if we've got union-wait, we'll automatically use it.
+dnl
+dnl Garrett Wollman adds:
+dnl    The tests described above don't quite do the right thing,
+dnl    since some systems have hacks which allow `union wait' to
+dnl    still work even though `int' is preferred (and generates
+dnl    fewer warnings).  Since all of these systems use prototypes,
+dnl    we can use the prototype of wait(2) to disambiguate them.
+dnl
+dnl Alexandre Oliva adds:
+dnl     A single compile check is enough.  If we don't have union wait,
+dnl     it's obvious that the test will fail, and that we must use int.
+dnl     If we do, the prototype (on STDC systems) and WIFEXITED will tell
+dnl     whether we're supposed to be using union wait instead of int.
+dnl
+AC_DEFUN([CF_WAIT],
+[
+AC_REQUIRE([AC_TYPE_PID_T])
+AC_HAVE_HEADERS(sys/wait.h wait.h)
+AC_CACHE_CHECK([whether wait uses union wait], [cf_cv_arg_union_wait],
+        [AC_TRY_COMPILE([
+#include <sys/types.h>
+
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#else
+# if HAVE_WAIT_H
+#  include <wait.h>
+# endif
+#endif
+
+#ifdef __STDC__
+pid_t wait(union wait *);
+#endif
+], [
+  union wait x; int i;
+  wait(&x); i = WIFEXITED(x)
+], [cf_cv_arg_union_wait=yes], [cf_cv_arg_union_wait=no])])
+if test $cf_cv_arg_union_wait = yes; then
+       AC_DEFINE(WAIT_USES_UNION,1,[Defined if wait() puts the status in a union wait instead of int. ])
+fi
+])dnl
+
+
+dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])]
+dnl
+dnl the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
+dnl existence of an include file <stdint.h> that defines a set of 
+dnl typedefs, especially uint8_t,int32_t,uintptr_t.
+dnl Many older installations will not provide this file, but some will
+dnl have the very same definitions in <inttypes.h>. In other enviroments
+dnl we can use the inet-types in <sys/types.h> which would define the
+dnl typedefs int8_t and u_int8_t respectivly.
+dnl
+dnl This macros will create a local "_stdint.h" or the headerfile given as 
+dnl an argument. In many cases that file will just "#include <stdint.h>" 
+dnl or "#include <inttypes.h>", while in other environments it will provide 
+dnl the set of basic 'stdint's definitions/typedefs: 
+dnl   int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t
+dnl   int_least32_t.. int_fast32_t.. intmax_t
+dnl which may or may not rely on the definitions of other files,
+dnl or using the AC_CHECK_SIZEOF macro to determine the actual
+dnl sizeof each type.
+dnl
+dnl if your header files require the stdint-types you will want to create an
+dnl installable file mylib-int.h that all your other installable header
+dnl may include. So if you have a library package named "mylib", just use
+dnl      AX_CREATE_STDINT_H(mylib-int.h) 
+dnl in configure.ac and go to install that very header file in Makefile.am
+dnl along with the other headers (mylib.h) - and the mylib-specific headers
+dnl can simply use "#include <mylib-int.h>" to obtain the stdint-types.
+dnl
+dnl Remember, if the system already had a valid <stdint.h>, the generated
+dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things...
+dnl
+dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/)
+dnl @version $Id: acinclude.m4i,v 1.1.2.5.6.2 2004/04/29 20:47:40 martinea Exp $
+dnl @author  Guido Draheim <guidod@gmx.de> 
+
+AC_DEFUN([AX_CREATE_STDINT_H],
+[# ------ AX CREATE STDINT H -------------------------------------
+AC_MSG_CHECKING([for stdint types])
+ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
+# try to shortcircuit - if the default include path of the compiler
+# can find a "stdint.h" header then we assume that all compilers can.
+AC_CACHE_VAL([ac_cv_header_stdint_t],[
+old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
+old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
+old_CFLAGS="$CFLAGS"     ; CFLAGS=""
+AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
+[ac_cv_stdint_result="(assuming C99 compatible system)"
+ ac_cv_header_stdint_t="stdint.h"; ],
+[ac_cv_header_stdint_t=""])
+CXXFLAGS="$old_CXXFLAGS"
+CPPFLAGS="$old_CPPFLAGS"
+CFLAGS="$old_CFLAGS" ])
+
+v="... $ac_cv_header_stdint_h"
+if test "$ac_stdint_h" = "stdint.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)])
+elif test "$ac_stdint_h" = "inttypes.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)])
+elif test "_$ac_cv_header_stdint_t" = "_" ; then
+ AC_MSG_RESULT([(putting them into $ac_stdint_h)$v])
+else
+ ac_cv_header_stdint="$ac_cv_header_stdint_t"
+ AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)])
+fi
+
+if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit..
+
+dnl .....intro message done, now do a few system checks.....
+dnl btw, all CHECK_TYPE macros do automatically "DEFINE" a type, therefore
+dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead
+
+inttype_headers=`echo $2 | sed -e 's/,/ /g'`
+
+ac_cv_stdint_result="(no helpful system typedefs seen)"
+AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[
+ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
+  AC_MSG_RESULT([(..)])
+  for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_uintptr_t 
+   unset ac_cv_type_uint64_t
+   _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen uintptr_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint uintptr_t])
+ ])
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[
+ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
+  AC_MSG_RESULT([(..)])
+  for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do
+   unset ac_cv_type_uint32_t
+   unset ac_cv_type_uint64_t
+   AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen uint32_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint uint32_t])
+ ])
+fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+if test "_$ac_cv_header_stdint_o" = "_" ; then
+AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[
+ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
+  AC_MSG_RESULT([(..)])
+  for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_u_int32_t
+   unset ac_cv_type_u_int64_t
+   AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen u_int32_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint u_int32_t])
+ ])
+fi fi
+
+dnl if there was no good C99 header file, do some typedef checks...
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+   AC_MSG_CHECKING([for stdint datatype model])
+   AC_MSG_RESULT([(..)])
+   AC_CHECK_SIZEOF(char)
+   AC_CHECK_SIZEOF(short)
+   AC_CHECK_SIZEOF(int)
+   AC_CHECK_SIZEOF(long)
+   AC_CHECK_SIZEOF(void*)
+   ac_cv_stdint_char_model=""
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model=""
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp"
+   name="$ac_cv_stdint_long_model"
+   case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in
+    122/242)     name="$name,  IP16 (standard 16bit machine)" ;;
+    122/244)     name="$name,  LP32 (standard 32bit mac/win)" ;;
+    122/*)       name="$name        (unusual int16 model)" ;; 
+    124/444)     name="$name, ILP32 (standard 32bit unixish)" ;;
+    124/488)     name="$name,  LP64 (standard 64bit unixish)" ;;
+    124/448)     name="$name, LLP64 (unusual  64bit unixish)" ;;
+    124/*)       name="$name        (unusual int32 model)" ;; 
+    128/888)     name="$name, ILP64 (unusual  64bit numeric)" ;;
+    128/*)       name="$name        (unusual int64 model)" ;; 
+    222/*|444/*) name="$name        (unusual dsptype)" ;;
+     *)          name="$name        (very unusal model)" ;;
+   esac
+   AC_MSG_RESULT([combined for stdint datatype model...  $name])
+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
+
+AC_MSG_CHECKING([for extra inttypes in chosen header])
+AC_MSG_RESULT([($ac_cv_header_stdint)])
+dnl see if int_least and int_fast types are present in _this_ header.
+unset ac_cv_type_int_least32_t
+unset ac_cv_type_int_fast32_t
+AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>])
+AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>])
+AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>])
+
+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
+
+AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl
+$ac_cv_stdint_result])
+
+# ----------------- DONE inttypes.h checks START header -------------
+AC_CONFIG_COMMANDS([$ac_stdint_h],[
+AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h)
+ac_stdint=$tmp/_stdint.h
+
+echo "#ifndef" $_ac_stdint_h >$ac_stdint
+echo "#define" $_ac_stdint_h "1" >>$ac_stdint
+echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
+echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
+echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_t" != "_" ; then 
+echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
+fi
+
+cat >>$ac_stdint <<STDINT_EOF
+
+/* ................... shortcircuit part ........................... */
+
+#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <stddef.h>
+
+/* .................... configured part ............................ */
+
+STDINT_EOF
+
+echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+  ac_header="$ac_cv_header_stdint_x"
+  echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
+fi
+
+echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_o" != "_" ; then
+  ac_header="$ac_cv_header_stdint_o"
+  echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
+fi
+
+echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_u" != "_" ; then
+  ac_header="$ac_cv_header_stdint_u"
+  echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
+fi
+
+echo "" >>$ac_stdint
+
+if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
+  echo "#include <$ac_header>" >>$ac_stdint
+  echo "" >>$ac_stdint
+fi fi
+
+echo "/* which 64bit typedef has been found */" >>$ac_stdint
+if test "$ac_cv_type_uint64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_UINT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
+fi
+if test "$ac_cv_type_u_int64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_U_INT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* which type model has been detected */" >>$ac_stdint
+if test "_$ac_cv_stdint_char_model" != "_" ; then
+echo "#define   _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint
+echo "#define   _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint
+else
+echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
+echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* whether int_least types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_least32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_LEAST32_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
+fi
+echo "/* whether int_fast types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_fast32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
+fi
+echo "/* whether intmax_t type was detected */" >>$ac_stdint
+if test "$ac_cv_type_intmax_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+  cat >>$ac_stdint <<STDINT_EOF
+/* .................... detections part ............................ */
+
+/* whether we need to define bitspecific types from compiler base types */
+#ifndef _STDINT_HEADER_INTPTR
+#ifndef _STDINT_HEADER_UINT32
+#ifndef _STDINT_HEADER_U_INT32
+#define _STDINT_NEED_INT_MODEL_T
+#else
+#define _STDINT_HAVE_U_INT_TYPES
+#endif
+#endif
+#endif
+
+#ifdef _STDINT_HAVE_U_INT_TYPES
+#undef _STDINT_NEED_INT_MODEL_T
+#endif
+
+#ifdef  _STDINT_CHAR_MODEL
+#if     _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
+#ifndef _STDINT_BYTE_MODEL
+#define _STDINT_BYTE_MODEL 12
+#endif
+#endif
+#endif
+
+#ifndef _STDINT_HAVE_INT_LEAST32_T
+#define _STDINT_NEED_INT_LEAST_T
+#endif
+
+#ifndef _STDINT_HAVE_INT_FAST32_T
+#define _STDINT_NEED_INT_FAST_T
+#endif
+
+#ifndef _STDINT_HEADER_INTPTR
+#define _STDINT_NEED_INTPTR_T
+#ifndef _STDINT_HAVE_INTMAX_T
+#define _STDINT_NEED_INTMAX_T
+#endif
+#endif
+
+
+/* .................... definition part ............................ */
+
+/* some system headers have good uint64_t */
+#ifndef _HAVE_UINT64_T
+#if     defined _STDINT_HAVE_UINT64_T  || defined HAVE_UINT64_T
+#define _HAVE_UINT64_T
+#elif   defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
+#define _HAVE_UINT64_T
+typedef u_int64_t uint64_t;
+#endif
+#endif
+
+#ifndef _HAVE_UINT64_T
+/* .. here are some common heuristics using compiler runtime specifics */
+#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+#elif !defined __STRICT_ANSI__
+#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+#define _HAVE_UINT64_T
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
+/* note: all ELF-systems seem to have loff-support which needs 64-bit */
+#if !defined _NO_LONGLONG
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#elif defined __alpha || (defined __mips && defined _ABIN32)
+#if !defined _NO_LONGLONG
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#endif
+  /* compiler/cpu type to define int64_t */
+#endif
+#endif
+#endif
+
+#if defined _STDINT_HAVE_U_INT_TYPES
+/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+
+/* glibc compatibility */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INT_MODEL_T
+/* we must guess all the basic types. Apart from byte-adressable system, */
+/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
+/* (btw, those nibble-addressable systems are way off, or so we assume) */
+
+dnl   /* have a look at "64bit and data size neutrality" at */
+dnl   /* http://unix.org/version2/whatsnew/login_64bit.html */
+dnl   /* (the shorthand "ILP" types always have a "P" part) */
+
+#if defined _STDINT_BYTE_MODEL
+#if _STDINT_LONG_MODEL+0 == 242
+/* 2:4:2 =  IP16 = a normal 16-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned long   uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          long    int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
+/* 2:4:4 =  LP32 = a 32-bit system derived from a 16-bit */
+/* 4:4:4 = ILP32 = a normal 32-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
+/* 4:8:4 =  IP32 = a 32-bit system prepared for 64-bit    */
+/* 4:8:8 =  LP64 = a normal 64-bit system                 */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* this system has a "long" of 64bit */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long   uint64_t;
+typedef          long    int64_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 448
+/*      LLP64   a 64-bit system derived from a 32-bit system */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* assuming the system has a "long long" */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long long uint64_t;
+typedef          long long  int64_t;
+#endif
+#else
+#define _STDINT_NO_INT32_T
+#endif
+#else
+#define _STDINT_NO_INT8_T
+#define _STDINT_NO_INT32_T
+#endif
+#endif
+
+/*
+ * quote from SunOS-5.8 sys/inttypes.h:
+ * Use at your own risk.  As of February 1996, the committee is squarely
+ * behind the fixed sized types; the "least" and "fast" types are still being
+ * discussed.  The probability that the "fast" types may be removed before
+ * the standard is finalized is high enough that they are not currently
+ * implemented.
+ */
+
+#if defined _STDINT_NEED_INT_LEAST_T
+typedef  int8_t    int_least8_t;
+typedef  int16_t   int_least16_t;
+typedef  int32_t   int_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_least64_t;
+#endif
+
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_least64_t;
+#endif
+  /* least types */
+#endif
+
+#if defined _STDINT_NEED_INT_FAST_T
+typedef  int8_t    int_fast8_t; 
+typedef  int       int_fast16_t;
+typedef  int32_t   int_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_fast64_t;
+#endif
+
+typedef uint8_t   uint_fast8_t; 
+typedef unsigned  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_fast64_t;
+#endif
+  /* fast types */
+#endif
+
+#ifdef _STDINT_NEED_INTMAX_T
+#ifdef _HAVE_UINT64_T
+typedef  int64_t       intmax_t;
+typedef uint64_t      uintmax_t;
+#else
+typedef          long  intmax_t;
+typedef unsigned long uintmax_t;
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INTPTR_T
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+/* we encourage using "long" to store pointer values, never use "int" ! */
+#if   _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
+typedef  unsinged int   uintptr_t;
+typedef           int    intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
+typedef        uint64_t uintptr_t;
+typedef         int64_t  intptr_t;
+#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#endif
+#endif
+#endif
+
+  /* shortcircuit*/
+#endif
+  /* once */
+#endif
+#endif
+STDINT_EOF
+    if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
+      AC_MSG_NOTICE([$ac_stdint_h is unchanged])
+    else
+      ac_dir=`AS_DIRNAME(["$ac_stdint_h"])`
+      AS_MKDIR_P(["$ac_dir"])
+      rm -f $ac_stdint_h
+      mv $ac_stdint $ac_stdint_h
+    fi
+],[# variables for create stdint.h replacement
+PACKAGE="$PACKAGE"
+VERSION="$VERSION"
+ac_stdint_h="$ac_stdint_h"
+_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h)
+ac_cv_stdint_message="$ac_cv_stdint_message"
+ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
+ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
+ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
+ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_stdint_char_model="$ac_cv_stdint_char_model"
+ac_cv_stdint_long_model="$ac_cv_stdint_long_model"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
+])
+])
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 47 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+m4_ifdef([AC_PROVIDE_IFELSE],
+         [],
+         [m4_define([AC_PROVIDE_IFELSE],
+                [m4_ifdef([AC_PROVIDE_$1],
+                          [$2], [$3])])])
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+  AC_PROVIDE_IFELSE([AC_PROG_CXX],
+    [AC_LIBTOOL_CXX],
+    [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+  ])])
+dnl And a similar setup for Fortran 77 support
+  AC_PROVIDE_IFELSE([AC_PROG_F77],
+    [AC_LIBTOOL_F77],
+    [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+  AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+    [AC_LIBTOOL_GCJ],
+    [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+      [AC_LIBTOOL_GCJ],
+      [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+       [AC_LIBTOOL_GCJ],
+      [ifdef([AC_PROG_GCJ],
+            [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([A][M_PROG_GCJ],
+            [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([LT_AC_PROG_GCJ],
+            [define([LT_AC_PROG_GCJ],
+               defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
+])])# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+AC_LIBTOOL_SYS_MAX_CMD_LEN
+AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+AC_LIBTOOL_OBJDIR
+
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+_LT_AC_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
+
+# Same as above, but do not quote variable references.
+[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    AC_PATH_MAGIC
+  fi
+  ;;
+esac
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+       [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+AC_ARG_WITH([pic],
+    [AC_HELP_STRING([--with-pic],
+       [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+AC_LIBTOOL_LANG_C_CONFIG
+_LT_AC_TAGCONFIG
+])# AC_LIBTOOL_SETUP
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+AC_DEFUN([_LT_AC_SYS_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_AC_SYS_COMPILER
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
+[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+AC_DEFUN([_LT_AC_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+            [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+        [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[_LT_AC_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+[$]*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+        test "X$echo_testing_string" = "X$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+         then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "[$]0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+])])# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+AC_DEFUN([_LT_AC_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+       [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+  ])
+esac
+
+need_locks="$enable_libtool_lock"
+
+])# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#              [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+  ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   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
+     if test ! -s conftest.err; then
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$5], , :, [$5])
+else
+    ifelse([$6], , :, [$6])
+fi
+])# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                          [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
+[AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+     else
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$4], , :, [$4])
+else
+    ifelse([$5], , :, [$5])
+fi
+])# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
+[# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+ *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+              = "XX$teststring") >/dev/null 2>&1 &&
+           new_result=`expr "X$teststring" : ".*" 2>&1` &&
+           lt_cv_sys_max_cmd_len=$new_result &&
+           test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+])# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)dnl
+])# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}]
+EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_unknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+               [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+   ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+         [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+           [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+       [AC_CHECK_FUNC([dlopen],
+             [lt_cv_dlopen="dlopen"],
+         [AC_CHECK_LIB([dl], [dlopen],
+               [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+           [AC_CHECK_LIB([svld], [dlopen],
+                 [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+             [AC_CHECK_LIB([dld], [dld_link],
+                   [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+             ])
+           ])
+         ])
+       ])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+         lt_cv_dlopen_self, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+           lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+         lt_cv_dlopen_self_static, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+           lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+])
+])# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
+[AC_REQUIRE([_LT_AC_LOCK])dnl
+
+hard_links="nottested"
+if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+AC_DEFUN([AC_LIBTOOL_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+])# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_AC_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
+   test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \
+   test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_AC_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
+[striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         AC_MSG_RESULT([yes])
+       else
+  AC_MSG_RESULT([no])
+fi
+       ;;
+   *)
+  AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+])# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
+[AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+AC_DEFUN([_LT_AC_TAGCONFIG],
+[AC_ARG_WITH([tags],
+    [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
+        [include additional configurations @<:@automatic@:>@])],
+    [tagnames="$withval"])
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    AC_MSG_WARN([output file `$ofile' does not exist])
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+    else
+      AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+    fi
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
+    "") ;;
+    *)  AC_MSG_ERROR([invalid tag name: $tagname])
+       ;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      AC_MSG_ERROR([tag name \"$tagname\" already exists])
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+       if test -n "$CXX" && test "X$CXX" != "Xno"; then
+         AC_LIBTOOL_LANG_CXX_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      F77)
+       if test -n "$F77" && test "X$F77" != "Xno"; then
+         AC_LIBTOOL_LANG_F77_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      GCJ)
+       if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+         AC_LIBTOOL_LANG_GCJ_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      RC)
+       AC_LIBTOOL_LANG_RC_CONFIG
+       ;;
+
+      *)
+       AC_MSG_ERROR([Unsupported tag name: $tagname])
+       ;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    AC_MSG_ERROR([unable to update list of available tagged configurations.])
+  fi
+fi
+])# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN],
+ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([shared],
+    [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+       [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_shared=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
+])# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+#- set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)
+])# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([static],
+    [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+       [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_static=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]AC_ENABLE_STATIC_DEFAULT)
+])# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)
+])# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([fast-install],
+    [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_fast_install=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
+])# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)
+])# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)
+])# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+   [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])])
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+])# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+    [AC_HELP_STRING([--with-gnu-ld],
+       [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+])# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case "$host_cpu" in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  case $host_cpu in
+  alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*)
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+])# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm="$ac_dir/${ac_tool_prefix}nm"
+    if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+      */dev/null* | *'Invalid file or object type'*)
+       lt_cv_path_NM="$tmp_nm -B"
+       break
+        ;;
+      *)
+       case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+       */dev/null*)
+         lt_cv_path_NM="$tmp_nm -p"
+         break
+         ;;
+       *)
+         lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+         ;;
+       esac
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+])# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+])# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments.  Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
+# DIRECTORY is not provided, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments.  Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
+# DIRECTORY is not provided and an installed libltdl is not found, it is
+# assumed to be `libltdl'.  LIBLTDL will be prefixed with '${top_builddir}/'
+# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
+# quotes!).  If your package is not flat and you're not using automake,
+# define top_builddir and top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, lt_dlinit,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    LTDLINCL=
+  fi
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX],
+[AC_REQUIRE([_LT_AC_LANG_CXX])
+])# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+AC_DEFUN([_LT_AC_LANG_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
+])# _LT_AC_LANG_CXX
+
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+AC_DEFUN([AC_LIBTOOL_F77],
+[AC_REQUIRE([_LT_AC_LANG_F77])
+])# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+AC_DEFUN([_LT_AC_LANG_F77],
+[AC_REQUIRE([AC_PROG_F77])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
+])# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],
+[AC_REQUIRE([_LT_AC_LANG_GCJ])
+])# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+AC_DEFUN([_LT_AC_LANG_GCJ],
+[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+    [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+      [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+        [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+          [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
+])# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# --------------
+# enable support for Windows resource files
+AC_DEFUN([AC_LIBTOOL_RC],
+[AC_REQUIRE([LT_AC_PROG_RC])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
+])# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
+AC_DEFUN([_LT_AC_LANG_C_CONFIG],
+[lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+_LT_AC_SYS_COMPILER
+
+#
+# Check for any special shared library compilation flags.
+#
+_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)=
+if test "$GCC" = no; then
+  case $host_os in
+  sco3.2v5*)
+    _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf'
+    ;;
+  esac
+fi
+if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then
+  AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries])
+  if echo "$old_CC $old_CFLAGS " | grep "[[    ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[        ]]" >/dev/null; then :
+  else
+    AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure])
+    _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no
+  fi
+fi
+
+
+#
+# Check to make sure the static flag actually works.
+#
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works],
+  _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+  $_LT_AC_TAGVAR(lt_prog_compiler_static, $1),
+  [],
+  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+# Report which librarie types wil actually be built
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+  darwin* | rhapsody*)
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    output_verbose_link_cmd='echo'
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring'
+    _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag  -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+  else
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+  fi
+    ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
+AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
+[AC_LANG_PUSH(C++)
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Dependencies to place before and after the object being linked:
+_LT_AC_TAGVAR(predep_objects, $1)=
+_LT_AC_TAGVAR(postdep_objects, $1)=
+_LT_AC_TAGVAR(predeps, $1)=
+_LT_AC_TAGVAR(postdeps, $1)=
+_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
+
+# Source file extension for C++ test sources.
+ac_ext=cc
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+else
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+  AC_PROG_LD
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+       grep 'no-whole-archive' > /dev/null; then
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+       for ld_flag in $LDFLAGS; do
+         case $ld_flag in
+         *-brtl*)
+           aix_use_runtimelinking=yes
+           break
+           ;;
+         esac
+       done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    _LT_AC_TAGVAR(archive_cmds, $1)=''
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.[012]|aix4.[012].*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+       collect2name=`${CC} -print-prog-name=collect2`
+       if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+       then
+         # We have reworked collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+       else
+         # We have old collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+       fi
+      esac
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+       shared_flag='-G'
+      else
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag='${wl}-G'
+       else
+         shared_flag='${wl}-bM:SRE'
+       fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      _LT_AC_SYS_LIBPATH_AIX
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+       # Warning - without using the other run time loading flags,
+       # -berok will link without error, but may produce a broken library.
+       _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+       # -bexpall does not export symbols beginning with underscore (_)
+       _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+       # Exported symbols can be pulled into shared objects from archives
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+       _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+       # This is similar to how AIX traditionally builds it's shared libraries.
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+  chorus*)
+    case $cc_basename in
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+    # as there is no search path for DLLs.
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+    _LT_AC_TAGVAR(always_export_symbols, $1)=no
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+       cp $export_symbols $output_objdir/$soname.def;
+      else
+       echo EXPORTS > $output_objdir/$soname.def;
+       cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+  ;;
+
+  darwin* | rhapsody*)
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    lt_int_apple_cc_single_mod=no
+    output_verbose_link_cmd='echo'
+    if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+      lt_int_apple_cc_single_mod=yes
+    fi
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    else
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    fi
+    _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+  else
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+  fi
+    ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      ghcx)
+       # Green Hills C++ Compiler
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  freebsd[12]*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  freebsd-elf*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  freebsd* | kfreebsd*-gnu)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                               # but as the default
+                               # location of the library.
+
+    case $cc_basename in
+    CC)
+      # FIXME: insert proper C++ library support
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    aCC)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      case "$host_cpu" in
+      hppa*64*)
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+        ;;
+      ia64*)
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+        ;;
+      *)
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        ;;
+      esac
+    fi
+    case "$host_cpu" in
+    hppa*64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+    ia64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    *)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      aCC)
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       esac
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test $with_gnu_ld = no; then
+           case "$host_cpu" in
+           ia64*|hppa*64*)
+             _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+             ;;
+           *)
+             _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           esac
+         fi
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC)
+       # SGI C++
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+       # Archives containing C++ object files must be created using
+       # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test "$with_gnu_ld" = no; then
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+         else
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+         fi
+       fi
+       _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+       ;;
+    esac
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+       ;;
+      icpc)
+       # Intel C++
+       with_gnu_ld=yes
+       _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+       ;;
+      cxx)
+       # Compaq C++
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+       runpath_var=LD_RUN_PATH
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+
+       ;;
+      RCC)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      cxx)
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Archives containing C++ object files must be created using
+       # the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
+       ;;
+      RCC)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      cxx)
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+         echo "-hidden">> $lib.exp~
+         $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~
+         $rm $lib.exp'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  sco*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case $cc_basename in
+      CC)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC)
+       # Sun C++ 4.x
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      lcc)
+       # Lucid
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC)
+       # Sun C++ 4.2, 5.x and Centerline C++
+       _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+       case $host_os in
+         solaris2.[0-5] | solaris2.[0-5].*) ;;
+         *)
+           # The C++ compiler is used as linker so we must use $wl
+           # flag to pass the commands to the underlying system
+           # linker.
+           # Supported since Solaris 2.6 (maybe 2.5.1?)
+           _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+           ;;
+       esac
+       _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       # Archives containing C++ object files must be created using
+       # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+       ;;
+      gcx)
+       # Green Hills C++ Compiler
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+       # The C++ compiler must be used to create the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+       ;;
+      *)
+       # GNU C++ compiler with Solaris linker
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+         if $CC --version | grep -v '^2\.7' > /dev/null; then
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         else
+           # g++ 2.7 appears to require `-G' NOT `-shared' on this
+           # platform.
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         fi
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+       fi
+       ;;
+    esac
+    ;;
+  sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC)
+       # NonStop-UX NCC 3.20
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+esac
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$GXX"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_POSTDEP_PREDEP($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+])# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
+int a;
+void foo (void) { a = 0; }
+EOF
+],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+],[$1],[F77],[cat > conftest.$ac_ext <<EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+EOF
+],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+         || test $p = "-R"; then
+        prev=$p
+        continue
+       else
+        prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        case $p in
+        -L* | -R*)
+          # Internal compiler library paths should come after those
+          # provided the user.  The postdeps already come after the
+          # user supplied libs so there is no need to process them.
+          if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
+            _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+          else
+            _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+          fi
+          ;;
+        # The "-l" case would never come before the object being
+        # linked, so don't bother handling this case.
+        esac
+       else
+        if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
+          _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
+        else
+          _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
+        fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+        pre_test_object_deps_done=yes
+        continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
+          _LT_AC_TAGVAR(predep_objects, $1)="$p"
+        else
+          _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
+        fi
+       else
+        if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
+          _LT_AC_TAGVAR(postdep_objects, $1)="$p"
+        else
+          _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
+        fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$rm -f confest.$objext
+
+case " $_LT_AC_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+])# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
+AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
+[AC_REQUIRE([AC_PROG_F77])
+AC_LANG_PUSH(Fortran 77)
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$G77"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
+AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
+AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars.  Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+AC_DEFUN([AC_LIBTOOL_CONFIG],
+[# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    _LT_AC_TAGVAR(compiler, $1) \
+    _LT_AC_TAGVAR(CC, $1) \
+    _LT_AC_TAGVAR(LD, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
+    _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
+    _LT_AC_TAGVAR(old_archive_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
+    _LT_AC_TAGVAR(predep_objects, $1) \
+    _LT_AC_TAGVAR(postdep_objects, $1) \
+    _LT_AC_TAGVAR(predeps, $1) \
+    _LT_AC_TAGVAR(postdeps, $1) \
+    _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
+    _LT_AC_TAGVAR(archive_cmds, $1) \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(postinstall_cmds, $1) \
+    _LT_AC_TAGVAR(postuninstall_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
+    _LT_AC_TAGVAR(allow_undefined_flag, $1) \
+    _LT_AC_TAGVAR(no_undefined_flag, $1) \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
+    _LT_AC_TAGVAR(hardcode_automatic, $1) \
+    _LT_AC_TAGVAR(module_cmds, $1) \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+    _LT_AC_TAGVAR(exclude_expsyms, $1) \
+    _LT_AC_TAGVAR(include_expsyms, $1); do
+
+    case $var in
+    _LT_AC_TAGVAR(old_archive_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(module_cmds, $1) | \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\[$]0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
+    ;;
+  esac
+
+ifelse([$1], [],
+  [cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  AC_MSG_NOTICE([creating $ofile])],
+  [cfgfile="$ofile"])
+
+  cat <<__EOF__ >> "$cfgfile"
+ifelse([$1], [],
+[#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG],
+[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+
+# Is the compiler the GNU C compiler?
+with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
+archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
+module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+
+# Symbols that must always be exported.
+include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+
+ifelse([$1],[],
+[# ### END LIBTOOL CONFIG],
+[# ### END LIBTOOL TAG CONFIG: $tagname])
+
+__EOF__
+
+ifelse([$1],[], [
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+])
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+])# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+
+_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris* | sysv5*)
+  symcode='[[BDRT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[     ]]\($symcode$symcode*\)[[       ]][[    ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+       if grep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+         cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+         $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+         cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$ac_objext conftstm.$ac_objext
+         lt_save_LIBS="$LIBS"
+         lt_save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$ac_objext"
+         CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+         if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+           pipe_works=yes
+         fi
+         LIBS="$lt_save_LIBS"
+         CFLAGS="$lt_save_CFLAGS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
+[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+ ifelse([$1],[CXX],[
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       ;;
+      esac
+      ;;
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+       # All AIX code is PIC.
+       if test "$host_cpu" = ia64; then
+         # AIX 5 now supports IA64 processor
+         _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+       else
+         _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+       fi
+       ;;
+      chorus*)
+       case $cc_basename in
+       cxch68)
+         # Green Hills C++ Compiler
+         # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+         ;;
+       esac
+       ;;
+      dgux*)
+       case $cc_basename in
+         ec++)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           ;;
+         ghcx)
+           # Green Hills C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      freebsd* | kfreebsd*-gnu)
+       # FreeBSD uses GNU C++
+       ;;
+      hpux9* | hpux10* | hpux11*)
+       case $cc_basename in
+         CC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+           if test "$host_cpu" != ia64; then
+             _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+           fi
+           ;;
+         aCC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+           case "$host_cpu" in
+           hppa*64*|ia64*)
+             # +Z the default
+             ;;
+           *)
+             _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+             ;;
+           esac
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      irix5* | irix6* | nonstopux*)
+       case $cc_basename in
+         CC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           # CC pic flag -KPIC is the default.
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      linux*)
+       case $cc_basename in
+         KCC)
+           # KAI C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+           ;;
+         icpc)
+           # Intel C++
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+           ;;
+         cxx)
+           # Compaq C++
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      lynxos*)
+       ;;
+      m88k*)
+       ;;
+      mvs*)
+       case $cc_basename in
+         cxx)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      netbsd*)
+       ;;
+      osf3* | osf4* | osf5*)
+       case $cc_basename in
+         KCC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+           ;;
+         RCC)
+           # Rational C++ 2.4.1
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         cxx)
+           # Digital/Compaq C++
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      psos*)
+       ;;
+      sco*)
+       case $cc_basename in
+         CC)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      solaris*)
+       case $cc_basename in
+         CC)
+           # Sun C++ 4.2, 5.x and Centerline C++
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+           ;;
+         gcx)
+           # Green Hills C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sunos4*)
+       case $cc_basename in
+         CC)
+           # Sun C++ 4.x
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           ;;
+         lcc)
+           # Lucid
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      tandem*)
+       case $cc_basename in
+         NCC)
+           # NonStop-UX NCC 3.20
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      unixware*)
+       ;;
+      vxworks*)
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+       ;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      ccc*)
+        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn'
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
+    _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1),
+    [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+])
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
+[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ifelse([$1],[CXX],[
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+],[
+  runpath_var=
+  _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+  _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_AC_TAGVAR(archive_cmds, $1)=
+  _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+  _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+  _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_AC_TAGVAR(hardcode_automatic, $1)=no
+  _LT_AC_TAGVAR(module_cmds, $1)=
+  _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(always_export_symbols, $1)=no
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_AC_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=no
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds"
+      fi
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then
+      runpath_var=LD_RUN_PATH
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+       else
+         _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_AC_TAGVAR(archive_cmds, $1)=''
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.[012]|aix4.[012].*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+         else
+         # We have old collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+         fi
+       esac
+       shared_flag='-shared'
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+       if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+       fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        _LT_AC_SYS_LIBPATH_AIX
+        _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+         # -bexpall does not export symbols beginning with underscore (_)
+         _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+         # Exported symbols can be pulled into shared objects from archives
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+         # This is similar to how AIX traditionally builds it's shared libraries.
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      # see comment about different semantics on the GNU ld section
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    bsdi4*)
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      case "$host_os" in
+      rhapsody* | darwin1.[[012]])
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+       ;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+       ;;
+      esac
+       lt_int_apple_cc_single_mod=no
+       output_verbose_link_cmd='echo'
+       if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+         lt_int_apple_cc_single_mod=yes
+       fi
+       if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+       else
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+      ;;
+
+    dgux*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*)
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+         _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+         ;;
+       ia64*)
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+         _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         ;;
+       *)
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+         _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    openbsd*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      else
+       case $host_os in
+        openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+          _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+          ;;
+        *)
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    sco3.2v5*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+      esac
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+        ;;
+       motorola)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[[78]]* | unixware7*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv5*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_AC_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+        then
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+])# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+])# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+  test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+  AC_SUBST(GCJFLAGS)
+])
+
+AC_DEFUN([LT_AC_PROG_RC],
+[AC_CHECK_TOOL(RC, windres, no)
+])
+
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && break
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+SED=$lt_cv_path_SED
+])
+AC_MSG_RESULT([$SED])
+])
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..1402b2e
--- /dev/null
@@ -0,0 +1,966 @@
+# generated automatically by aclocal 1.8.4 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# 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.
+
+#                                                        -*- Autoconf -*-
+# Copyright (C) 2002, 2003  Free Software Foundation, Inc.
+# Generated from amversion.in; do not edit by hand.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+        [AM_AUTOMAKE_VERSION([1.8.4])])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                              -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 6
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# serial 7                                             -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[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
+
+  am_cv_$1_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_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking.   -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`AS_DIRNAME("$mf")`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`AS_DIRNAME(["$file"])`
+    AS_MKDIR_P([$dirpart/$fdir])
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 7
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                            -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 11
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                  [_AM_DEPENDENCIES(CC)],
+                  [define([AC_PROG_CC],
+                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                  [_AM_DEPENDENCIES(CXX)],
+                  [define([AC_PROG_CXX],
+                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $1 | $1:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+#                                                          -*- Autoconf -*-
+# Copyright (C) 2003  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 4
+
+# AM_PROG_LEX
+# -----------
+# Autoconf leaves LEX=: if lex or flex can't be found.  Change that to a
+# "missing" invocation, for better error output.
+AC_DEFUN([AM_PROG_LEX],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AM_MISSING_HAS_RUN])dnl
+AC_REQUIRE([AC_PROG_LEX])dnl
+if test "$LEX" = :; then
+  LEX=${am_missing_run}flex
+fi])
+
+# Check to see how 'make' treats includes.     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[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.
+AC_MSG_CHECKING([for style of include used by $am_make])
+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
+# 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
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+#  -*- Autoconf -*-
+
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+
+# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake.  There are at least two reasons why we must not
+# use `-m 0755':
+#   - it causes special bits like SGID to be ignored,
+#   - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out.  Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # Keeping the `.' argument allows $(mkdir_p) to be used without
+  # argument.  Indeed, we sometimes output rules like
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.
+  # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+  # expensive solution, as it forces Make to start a sub-shell.)
+  mkdir_p='mkdir -p -- .'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling.                    -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+m4_include([acinclude.m4])
diff --git a/amplot/Makefile.am b/amplot/Makefile.am
new file mode 100644 (file)
index 0000000..1efc993
--- /dev/null
@@ -0,0 +1,44 @@
+# Makefile for amplot.
+
+SUFFIXES =             .sh
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+sbin_SCRIPTS =         amplot
+
+amplot_DATA =          amcat.awk amplot.awk amplot.g amplot.gp
+
+amplotdir =            $(libexecdir)
+
+EXTRA_DIST =           amplot.awk              amplot.g
+
+CLEANFILES = amplot.gp.new
+DISTCLEANFILES = amplot.gp
+
+amplot.gp:             amplot.g
+                       cat $(srcdir)/amplot.g > amplot.gp.new
+                       echo "pause -1;" >> amplot.gp.new
+                       rm -f amplot.gp
+                       mv amplot.gp.new amplot.gp
+
+install-exec-hook:
+       @list="$(sbin_SCRIPTS)"; \
+       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; \
+       done
+
+install-data-hook:
+       @list="$(amplot_DATA)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(libexecdir)/$$p; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+        done
diff --git a/amplot/Makefile.in b/amplot/Makefile.in
new file mode 100644 (file)
index 0000000..66a34be
--- /dev/null
@@ -0,0 +1,499 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 amplot.
+
+
+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 = :
+host_triplet = @host@
+subdir = amplot
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+       $(srcdir)/amcat.awk.in $(srcdir)/amplot.sh.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 = amcat.awk amplot.sh
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(amplotdir)"
+sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(sbin_SCRIPTS)
+SOURCES =
+DIST_SOURCES =
+amplotDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(amplot_DATA)
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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@
+SUFFIXES = .sh
+sbin_SCRIPTS = amplot
+amplot_DATA = amcat.awk amplot.awk amplot.g amplot.gp
+amplotdir = $(libexecdir)
+EXTRA_DIST = amplot.awk                amplot.g
+CLEANFILES = amplot.gp.new
+DISTCLEANFILES = amplot.gp
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .sh
+$(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  amplot/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  amplot/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
+amcat.awk: $(top_builddir)/config.status $(srcdir)/amcat.awk.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amplot.sh: $(top_builddir)/config.status $(srcdir)/amplot.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-sbinSCRIPTS: $(sbin_SCRIPTS)
+       @$(NORMAL_INSTALL)
+       test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+       @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         if test -f $$d$$p; then \
+           f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+           echo " $(sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+           $(sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \
+         else :; fi; \
+       done
+
+uninstall-sbinSCRIPTS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+         echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+       done
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+install-amplotDATA: $(amplot_DATA)
+       @$(NORMAL_INSTALL)
+       test -z "$(amplotdir)" || $(mkdir_p) "$(DESTDIR)$(amplotdir)"
+       @list='$(amplot_DATA)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(amplotDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(amplotdir)/$$f'"; \
+         $(amplotDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(amplotdir)/$$f"; \
+       done
+
+uninstall-amplotDATA:
+       @$(NORMAL_UNINSTALL)
+       @list='$(amplot_DATA)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f '$(DESTDIR)$(amplotdir)/$$f'"; \
+         rm -f "$(DESTDIR)$(amplotdir)/$$f"; \
+       done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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 $(SCRIPTS) $(DATA)
+installdirs:
+       for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(amplotdir)"; 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:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-amplotDATA
+       @$(NORMAL_INSTALL)
+       $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+
+install-exec-am: install-sbinSCRIPTS
+       @$(NORMAL_INSTALL)
+       $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-amplotDATA uninstall-info-am \
+       uninstall-sbinSCRIPTS
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-libtool distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-amplotDATA install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-sbinSCRIPTS install-strip installcheck installcheck-am \
+       installdirs maintainer-clean maintainer-clean-generic \
+       mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+       ps ps-am uninstall uninstall-am uninstall-amplotDATA \
+       uninstall-info-am uninstall-sbinSCRIPTS
+
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+amplot.gp:             amplot.g
+                       cat $(srcdir)/amplot.g > amplot.gp.new
+                       echo "pause -1;" >> amplot.gp.new
+                       rm -f amplot.gp
+                       mv amplot.gp.new amplot.gp
+
+install-exec-hook:
+       @list="$(sbin_SCRIPTS)"; \
+       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; \
+       done
+
+install-data-hook:
+       @list="$(amplot_DATA)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(libexecdir)/$$p; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+        done
+# 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/amplot/amcat.awk.in b/amplot/amcat.awk.in
new file mode 100644 (file)
index 0000000..f5b65f9
--- /dev/null
@@ -0,0 +1,6 @@
+BEGIN{o=substr(f,length(f)-1,2);
+if(substr(o,1,1)==".") o=substr(o,2,1);
+@AMPLOT_CAT_GZIP@
+@AMPLOT_CAT_COMPRESS@
+@AMPLOT_CAT_PACK@
+print "cat"; exit; }
diff --git a/amplot/amplot.awk b/amplot/amplot.awk
new file mode 100644 (file)
index 0000000..97f2dd5
--- /dev/null
@@ -0,0 +1,526 @@
+#
+# Amanda, The Advanced Maryland Automatic Network Disk Archiver
+# Copyright (c) 1992-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.
+#
+# Author: Olafur Gudumundsson, ogud@tis.com
+# formerly at:     Systems Design and Analysis Group
+#                 Computer Science Department
+#                 University of Maryland at College Park
+#
+# An awk program to parse the amdump file and output the information
+# in a form at the gnuplot program amplot.g wants
+#
+#      Creation Date: April 1992
+#      modified: Aug 1993
+#       Modified for Amanda-2.2: Dec 1993
+#       Modified for Amanda-2.2: Mar 1994 and May 1994 and June 1994
+#       Enhanced: April 1995
+#      Input: One amdump file 
+#      Output: Number of files that get fed into gnuplot
+#
+BEGIN{
+# The folowing parameters may have to be set to suit each site, both 
+# parameters are expressed in HOUR's. 
+# If your average amanda dump is more than 3 hours you should increase the
+# value of maxtime, similary if your dumps are finishing in less than 2 hours
+# you should decrease the value of maxtime.
+# This is now setable from amplot's command line.
+#      maxtime  = 4;                   # how long to plot graph for in hours
+
+# Min host controls the reporting of hosts that take long in dumping
+# This varible can be set explicity or as a fraction of maxtime
+# If you are seeing too many hosts reported increase the value of this 
+# constant
+#
+       min_host = maxtime * 0.75;      # good rule of thumb
+#      min_host = 2.5;                 # expicit cutoff value in hours
+
+#
+# DO NOT CHANGE ANYTHING BELOW THIS LINE
+#
+       time_scale = 60;        # display in minutes DO NOT CHANGE
+       maxtime  *= time_scale; # convert to minutes
+       min_host *= time_scale *time_scale; # convert to seconds
+                                                # dumping than this 
+        disk_raise = 120;      # scaling factors for Holding disk graph
+        tape_raise = 90;
+       dump_shift = 7.5;       # scaling factors for Dumpers idle graph
+       dump_raise = 0;
+       que_raise  = 300;       # scaling factors for the queue's
+       count_scale= 1.0/3.0;   # new scale 
+                               # scaling factors for the x axis 
+       bandw_raise = 250;
+       bandw_scale = 30/300;   # default calculated below 
+
+       holding_disk = -1;      # uninitialized
+               
+       cnt        = 0;         # default values for counters
+       din        = 0;         # number of dumps to holding disk
+       dout       = 0;         # number of dumps to tape 
+       tapeq      = 0;         # how many dumps in tape queue
+       tape_err   = 0;         # how many tape errors
+       tout       = 0;         # data written out to tape 
+       quit       = 0;         # normal end of run
+       plot_fmt   = "%7.2f %6.2f\n%7.2f %6.2f\n";  # format of files for gnuplot
+       plot_fmt1  = "%7.2f %6.2f\n";  # format of files for gnuplot
+}
+       
+{              # state machine for processing input lines lines
+       if( $1 == "driver:") {
+               if($2=="result")            do_result();
+               else if( $2=="state")       do_state();
+               else if( $2=="interface-state") ;
+               else if( $2=="hdisk-state") do_hdisk++;
+               else if( $2=="flush" && $3=="size" ) {
+                       flush_size = $4;
+               }
+               else if( $2=="start")       do_start();
+               else if( $2=="send-cmd") { 
+                       if( $7=="FILE-DUMP"){
+                         file_dump++;
+                         dmpr_strt[$6]=$4;
+                         host[$6]=$10;
+                         disk[$6]=$12;
+                         level[$6]=$14;
+                       }
+                       else if( $7 == "FILE-WRITE") file_write++;
+                       else if( $7 == "START-TAPER") fil = $8;
+               }
+               else if( $2=="finished-cmd") cmd_fin++;
+               else if ($2=="started")      forked++;
+               else if( $2=="QUITTING")     do_quit();
+               else if( $2=="dumping" || $2 == "adding" || $2 == "holding-disks:") 
+                 dumping++; # eat this line
+               else if( $2!="FINISHED" && $2 != "pid" && $2 != "taper-tryagain"&& $2!="startaflush:")
+                 print fil,"Unknown statement#",$0;
+       }
+       else if ( $1 == "planner:") {
+               if( $2 == "SKIPPED" || $2 == "FAILED") {
+                       failed++;
+                       print fil, "INFO#", $0;
+               }
+       }
+       else if( $1 == "GENERATING")        sched_start=NR;
+       else if( $1 == "ENDFLUSH")          sched_start=NR;
+       else if( $1 == "DELAYING")          do_moves();    # find estimated size
+       else if( $1 == "dumper:") {
+               if($4 != "starting" && $2 != "pid" && $2 != "stream_client:" && $2 != "dgram_bind:") 
+                   print fil, "INFO#", $0;
+       }
+       else if( $1 == "taper:") {
+               if($3 != "label" && $3 != "end" && $2 != "DONE" && $2 != "pid" && $2 != "slot" && $2 != "reader-side:" && $2 != "page" && $2 != "buffer" && $3 != "at")
+                   print fil, "INFO#", $0;
+       }
+       else if( $1 == "FLUSH") {
+               no_flush++;
+       }
+       else if( NF==1 && sched_start > 0 && NR-sched_start > 1) { # new style end of schedule
+               no_disks = NR-sched_start-2; # lets hope there are no extra lines
+               sched_start = 0;
+       }
+}
+
+function do_state(){           # state line is printed out after driver
+                               # finishes pondering new actions
+                               # it reports the state as seen be driver
+# fields in the state line 
+# $2 = "state"                 # $3 = "time"           # $4 = time_val
+# $5 = "free"          # $6 = "kps:"           # $7 =  free_kps
+# $8 = "space:"                # $9 = space            # $10 = "taper:"
+# $11 = "writing"/"idle"# $12 = "idle-dumpers:"
+# $13 = #idle          # $14 = "qlen"          # $15 = "tapeq:"
+# $16 = #waiting       # $17 = "runq:"         # $18 = #not started 
+# $19 = "stoppedq:"    # $20 = #stopped
+
+       cnt++;                                  # number of event
+       time = $4/time_scale;
+       unused = (bandw - $7)*bandw_scale+bandw_raise;
+       if( unused != unused_old) 
+               printf plot_fmt, time, unused_old, time,unused >>"bandw_free";
+       unused_old = unused;
+
+       if(holding_disk_old != $9) {
+               disk_alloc_time[disk_a] = time;
+               disk_alloc_space[disk_a] = holding_disk_old;
+               disk_a++;
+               disk_alloc_time[disk_a] = time;
+               disk_alloc_space[disk_a] = $9;
+               disk_a++;
+               holding_disk_old = $9;
+       }
+
+       twait = tsize;
+       if(twait_old != twait) {
+               twait_time[twait_a] = time;
+               twait_wait[twait_a] = twait_old;
+               twait_a++;
+               twait_time[twait_a] = time;
+               twait_wait[twait_a] = twait;
+               twait_a++;
+               twait_old = twait;
+       }
+
+       active = (dumpers-$13)*dump_shift+dump_raise;
+       if( active != active_old )
+               printf plot_fmt, time, active_old, time, active >> "dump_idle";
+       active_old = active;
+
+# tape on or off
+       if($11=="writing")state = tape_raise+10;
+       else              state = tape_raise;
+       if( state != state_old )
+               printf plot_fmt, time, state_old, time, state >> "tape_idle";
+       state_old = state;
+
+       run = $18*count_scale+que_raise;
+       if( run != run_old )
+               printf plot_fmt, time, run_old, time, run >> "run_queue";
+       run_old = run;
+
+       finish = written * count_scale+que_raise;
+       if( finish != finish_old )
+               printf plot_fmt, time, finish_old, time, finish >> "finished";
+       finish_old = finish;
+
+       tapeQ = $16 * count_scale+que_raise;
+       if( tapeQ != tapeQ_old )
+               printf plot_fmt, time, tapeQ_old, time, tapeQ >> "tape_queue";
+       tapeQ_old = tapeQ;
+
+}
+
+function do_start() {          # get configuration parameters
+       dumpers    = $6;        # how many 
+       day        = $14;
+       dump_shift = 75/dumpers; 
+       bandw      = $8;                
+       bandw_scale = (30/bandw);
+       unused_old = bandw_raise;
+       print 0, unused_old > "bandw_free";
+       if( sched_start >0 ) {
+               no_disks = NR-sched_start-1; # backward compatability
+               sched_start =0;
+               print "do_start: no_disks", no_disks, $0;
+       }
+       no_disks += no_flush;
+       size        = $10/1024;        # size of holding disk in MB
+       holding_disk= $10 + flush_size;
+       init_holding_disk= $10 + flush_size;
+       holding_disk_old = $10;
+       disk_a = 0;
+       disk_alloc_time[disk_a] = 0;
+       disk_alloc_space[disk_a] = holding_disk_old;
+       disk_a++;
+       tsize = flush_size;
+       twait_old = tsize;
+       twait_a = 0;
+       twait_time[twait_a] = 0;
+       twait_wait[twait_a] = twait_old;
+       twait_a++;
+       if( NF==14) {           # original file was missing this
+               policy="FIFO";
+               alg   ="InOrder";
+       }
+       else if(NF>=18) {               # newer files have this format
+               policy = $18;
+               alg = $16;
+               if( alg=="drain-ends") big = $20; 
+       }
+       
+       start = $4;     # this is the start time of the first dump 
+                       # taper idle to this point should not be included
+       run_old = no_disks*cont_scale+que_raise;
+       print 0, run_old                >"run_queue";
+       finish_old = tapeQ_old = que_raise;
+       print 0, finish_old             >"finished";    
+       print 0, tapeQ_old              >"tape_queue" ; 
+       state_old = tape_raise;
+       print 0, state_old              > "tape_idle";
+       active_old = dump_raise;
+       print 0,active_old              >"dump_idle";
+
+}
+
+function do_quit(){            # this is issued by driver at the end
+                               # when it has nothing more to do
+       cnt++;
+       quit = 1;
+       tim  = $4 / time_scale;
+
+       disk_alloc_time[disk_a] = tim;
+       disk_alloc_space[disk_a] = holding_disk_old;
+       disk_a++;
+       max_space=disk_alloc_space[0];
+       for(a=0; a<disk_a; a++) {
+               if(disk_alloc_space[a] > max_space) {
+                       max_space = disk_alloc_space[a];
+               }
+       }
+
+       space_change = 0;
+       if(max_space > holding_disk) {
+               space_change = max_space - holding_disk;
+               holding_disk = max_space;
+       }
+
+       twait_time[twait_a] = tim;
+       twait_wait[twait_a] = twait_old;
+       twait_a++;
+       min_wait=twait_wait[0];
+       for(a=0; a<twait_a; a++) {
+               if(twait_wait[a] < min_wait) {
+                       min_wait = twait_wait[a];
+               }
+       }
+       if(min_wait < 0) {
+               if(flush_size == 0) {
+                       holding_disk -= min_wait;
+                       holding_disk -= space_change;
+               }
+               for(a=0; a<twait_a; a++) {
+                       twait_wait[a] -= min_wait;
+               }
+       }
+       if (holding_disk != 0) {
+               const = 100/holding_disk;
+       }
+       else {
+               const = 100;
+       }
+       for(a=0; a<disk_a; ++a) {
+               space = (holding_disk - disk_alloc_space[a])*const+disk_raise
+               printf plot_fmt1, disk_alloc_time[a], space >> "disk_alloc";
+       }
+       for(a=0; a<twait_a; ++a) {
+               space = (twait_wait[a])*const+disk_raise
+               printf plot_fmt1, twait_time[a], space >> "tape_wait";
+       }
+
+       printf plot_fmt, tim, active_old, tim, dump_raise >>"dump_idle";
+       printf plot_fmt, tim, state_old, tim, tape_raise >>"tape_idle"; 
+       printf plot_fmt, tim, unused_old, tim, bandw_raise >>"bandw_free";
+       printf plot_fmt, tim, finish_old, tim, written*count_scale+que_raise >>"finished";
+       printf plot_fmt, tim, run_old, tim, run_old >>"run_queue";
+}
+
+function do_result(){          # process lines driver: result
+       if($7=="DONE" ) {
+               if( $6=="taper:"){              # taper done
+                       tsize -= $14;   
+                       tout  += $14;
+                       tcnt--; written++;
+               }
+               else {                          # dumperx done 
+                 tsize += (int($15/32)+1)*32;  # in tape blocks 
+                 tcnt++;       done++;
+                 xx = host[$6];
+                 d = disk[$6];
+                 l = level[$6];
+                 host_time[xx]+= ( tt = $4 - dmpr_strt[$6]);
+                 if(xx in disk_list) disk_list[xx] = disk_list[xx] "\n";
+                 disk_list[xx] = disk_list[xx] \
+                                 xx ":" d "/" l "\t" \
+                                 pr_time(dmpr_strt[$6]) \
+                                 " - " pr_time($4) \
+                                 " = "  pr_time(tt);
+#                print host[$6], disk[host[$6]];
+#                      print host[$6], $4, dmpr_strt[$6], host_time[host[$6]]
+               }
+       }
+       else if ($6=="taper:") {                # something else than DONE
+               if($7=="TAPE-ERROR" || $7=="TRY-AGAIN") {
+                       tape_err= 1;
+                       err_time=$4/time_scale;
+               }
+               else if ($7=="TAPER-OK") tape_err=0;
+               else if ($7=="PORT")    tape_err=0;
+               else print fil, "UNKNOWN STATUS# "$0 ;
+       }
+       else {                                  # something bad from dumper 
+               if ($7=="FAILED") { failed++;}
+               else if ($7=="TRY-AGAIN"){ try++;}
+               else if ($7=="RQ-MORE-DISK") ;  # FIXME: ignore for now
+               else if ($7=="NO-ROOM")  
+                 print fil, pr_time($4),"#"  ++no_room, $0;
+               else if( $7=="ABORT-FINISHED") print fil, "#" ++no_abort, $0;
+               else print fil, "UNKNOWN STATUS# " $0;
+       }
+}
+
+function do_moves() { # function that extracts the estimated size of dumps
+                     # by processing DELAYING and promoting lines
+       est_size=$6;
+       getline ;                       # eat get next line print out planner msg
+       while (NF > 0 && (($1 == "delay:") || ($1 == "planner:")) ) {
+         if( $1 == "delay:") est_size = $NF;   # processing delay lines
+         else print fil, "DELAY#", $0;
+         getline;
+       }
+       getline ;                       # eating blank line
+       if( $1== "PROMOTING") {         # everything is dandy 
+               getline;                # get first promote line
+               while ( NF>0 && ($1 == "promote:" || $1 == "planner:" || $1 == "no" || $1 == "try") ) {
+                       if( $2 == "moving") {
+                               est_size=$8;
+                               print fil, "PROMOTING#", $1, $3;
+                       }
+                       else if($2 != "checking" && $2 != "can't" && $3 != "too" &&  $1 != "no" && $1 != "try" && $2 != "time")
+                            print fil,"PROMOTING#", $0;
+                       getline ;       # get next promote line
+               }
+       }
+       else print fil, "DID NOT FIND PROMOTING LINE IN THE RIGHT PLACE",NR,$0;
+}
+
+
+END {
+       if( holding_disk == -1) {               # bad input file 
+               print fil,": MISSING SPACE DECLARATION" ;
+               exit;
+       }
+# print headers of each graph  this is for the gnulot version 
+       if( tim >maxtime && extend==0)# if graph will extend beond borders
+         printf "Graph extends beond borders %s taking %7.3f > (max = %7.3f)\n",
+                       fil, tim, maxtime ;
+       print_t();                      # print titles
+       if( no_room + no_abort > 0) 
+            printf "NO-ROOM=%5d ABORT-FINISHED=%5d\n",  no_room, no_abort;
+       max_out = 20;
+       old_t = min_host * min_host;  # Some thing big
+       print "Longest dumping hosts   Times", min_host;
+       print "Host:disk/lev  \t start  -   end   =   run\t=> total";
+       while ( max_out-- > 0 && old_t > min_host) {
+         t = 0;
+         for (j in host_time) {
+           if( t < host_time[j] && host_time[j] <old_t){
+             t = host_time[d=j];
+           }
+         }
+         printf "%s\t=> %s\n\n", disk_list[d], pr_time(host_time[d]);
+#        printf "%-20.20s Total Dump time %s\n", d, pr_time(host_time[d]);
+         old_t = t;
+       }
+}
+
+function print_t(){            # printing out the labels for the graph 
+       label=0;                # calculating where labels go and 
+                               # range for x and y axes
+       maxy = int(no_disks/60+1)*20+que_raise;
+       printf "set yrange[0:%d]\n",maxy >"title";
+       if( maxtime < tim && extend !=0) {
+               printf "set xrange[0:%d]\n", tim+30 >>"title";
+               second_col = tim*0.5;
+               key_col = tim;
+               third_col = tim +13;
+       }
+       else {
+               printf "set xrange[0:%d]\n", maxtime >>"title";
+               second_col = (maxtime-10) * 0.5;
+               key_col = (maxtime-10) ;
+               third_col = maxtime +3;
+       }
+       label_shift = (7 + int(no_disks/100));
+       lab = label_start = maxy+(6*label_shift) ;  # showing 6 labels
+       printf "set key %d, %d\n", key_col, lab >>"title";
+       printf "set label %d \"Amanda Dump %s\" at 10,%d\n", ++label,fil, 
+               lab >"title";
+       lab -= label_shift;
+       printf "set label %d \"Bandwidth = %d\" at 10,%d\n",++label,bandw,
+               lab >>"title";
+
+       lab -= label_shift;
+       printf "set label %d \"Holding disk = %d\" at 10,%d\n",++label,size,
+               lab >>"title";
+
+       lab -= label_shift;
+       printf "set label %d \"Tape Policy = %s\" at 10,%d\n",++label,policy,
+               lab >>"title";
+
+       lab -= label_shift;
+       printf "set label %d \"Dumpers= %d\" at 10,%d\n",++label,dumpers,
+               lab >>"title";
+
+       lab -= label_shift;
+       if( alg =="drain-ends") 
+               printf "set label %d \"Driver alg = %s At big end %d\" at 10,%d\n",
+                       ++label,alg, big,lab >>"title";
+       else #if( alg =="InOrder")  # other special cases
+               printf "set label %d \"Driver alg = %s\" at 10,%d\n",
+                       ++label,alg, lab >>"title";
+
+       lab = label_start;
+       printf "set label %d \"Elapsed Time = %s\" at %d,%d\n",
+               ++label,pr_time(tim*60),second_col,lab >>"title";
+
+       lab -= label_shift;
+       if( tape_err==1)        stm = "TAPE ERROR";
+       else if( quit ==1)      stm = "SUCCESS";
+       else  {                 stm = "UNKNOWN";
+               print "Unknown terminating status",fil;
+       }
+       printf "set label %d \"Final status = %s\" at %d,%d\n",
+               ++label,stm, second_col,lab >> "title";
+
+       lab -= label_shift;
+       printf "set label %d \"Dumped/Failed = %3d/%d\" at %d,%d\n",
+               ++label,done,(failed+(try/2)), second_col,lab >>"title";
+
+       lab -= label_shift; 
+       printf "set label %d \"Output data size = %d\" at %d, %d\n",
+               ++label,int(tout/1024+0.49999),second_col,lab >>"title";
+       if( est_size >0) {
+               lab -= label_shift; 
+               printf "set label %d \"Estimated data size = %d\" at %d, %d\n",
+                       ++label,int(est_size/1024+0.49999),second_col,lab >>"title";
+       }
+
+       if (gnuplot==0) {
+               printf "set output \"%s.ps\"\n",fil >>"title";
+               if(bw==1) {
+                       if(paper==1) printf "set term postscript landscape \"Times-Roman\" 10\n" >>"title";
+                       else printf "set term postscript portrait \"Times-Roman\" 10\n" >>"title";
+               }
+               else {
+                       if(paper==1) printf "set term postscript landscape color \"Times-Roman\" 10\n" >>"title";
+                       else printf "set term postscript portrait color \"Times-Roman\" 10\n" >>"title";
+               }
+       }
+       printf "set ylabel """";" >>"title";    # make sure there is no ylabel
+       fmt= "set label %d \"%s\" at "third_col", %d\n";
+       printf fmt, ++label,"%DUMPERS", 40 >>"title";
+       printf fmt, ++label,"TAPE",  95 >>"title";
+       printf fmt, ++label,"HOLDING",180 >>"title";
+       printf fmt, ++label,"DISK", 160 >>"title";
+       printf fmt, ++label,"%BANDWIDTH", 260 >>"title";
+       printf fmt, ++label,"QUEUES",(que_raise+maxy)/2 >>"title";
+       if((paper+gnuplot) > 0) print "set size 0.9, 0.9;"  >>"title";
+       else                    print "set size 0.7,1.3;"   >>"title";
+}
+
+function pr_time(pr_a){ #function to pretty print time
+  pr_h = int(pr_a/3600);
+  pr_m = int(pr_a/60)%60;
+  pr_s = int(pr_a+0.5) %60;
+  if( pr_m < 10 && pr_s < 10 ) return  pr_h":0"pr_m":0"pr_s;
+  else if( pr_s < 10)          return  pr_h":" pr_m":0"pr_s;
+  else if( pr_m < 10)          return  pr_h":0"pr_m":" pr_s;
+  else                         return  pr_h":" pr_m":" pr_s;
+}
diff --git a/amplot/amplot.g b/amplot/amplot.g
new file mode 100644 (file)
index 0000000..9c5dd91
--- /dev/null
@@ -0,0 +1,69 @@
+#
+# Amanda, The Advanced Maryland Automatic Network Disk Archiver
+# Copyright (c) 1992,1993.1994-1998 University of Maryland at College Park
+# All Rights Reserved.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of U.M. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  U.M. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Author: Olafur Gudumundsson, (ogud@tis.com)  Trusted Information Systems
+# Formerly at:                   Systems Design and Analysis Group
+#                        Computer Science Department
+#                        University of Maryland at College Park
+#
+# program to print the summary graph for the amanda runs in gnupot
+# gnumaster.awk will generate the data for this one 
+#      Creation Date July 1992
+#      Last modified: May 1993
+#      Input: the files specified below on the  plot line
+#      Output: a postscript file 
+#
+set data style lines
+set xrange [0:210]
+set yrange [0:420]
+set xlabel "Minutes"
+#set xtics 0,10
+set xtics ( \
+    "0:00"   0, ""  10, "0:20"  20, ""  30, "0:40"  40, ""  50,\
+    "1:00"  60, ""  70, "1:20"  80, ""  90, "1:40" 100, "" 110,\
+    "2:00" 120, "" 130, "2:20" 140, "" 150, "2:40" 160, "" 170,\
+    "3:00" 180, "" 190, "3:20" 200, "" 210, "3:40" 220, "" 230,\
+    "4:00" 240, "" 250, "4:20" 260, "" 270, "4:40" 280, "" 290,\
+    "5:00" 300, "" 310, "5:20" 320, "" 330, "5:40" 340, "" 350,\
+    "6:00" 360, "" 370, "6:20" 380, "" 390, "6:40" 400, "" 410,\
+    "7:00" 420, "" 430, "7:20" 440, "" 450, "7:40" 460, "" 470,\
+    "8:00" 480, "" 490, "8:20" 500, "" 510, "8:40" 520, "" 530)
+
+set ytics ("0" 0, "20" 15, "40" 30, "60" 45, "80" 60, "100" 75,\
+       "Idle" 90,"Active" 100, \
+       "0" 120, "20" 140,"40" 160, "60" 180, "80" 200, "100" 220,\
+       "0" 250, "100" 280,\
+       "0"   300, "60"  320, "120" 340, "180" 360, "240" 380, "300" 400,\
+       "360" 420, "420" 440, "480" 460, "540" 480, "600" 500)
+
+#set size 0.7,1.3; set term postscript portrait "Times-Roman" 10
+#set size 0.9,0.9; set term postscript landscape "Times-Roman" 12
+# file title has the parameters that this program needs
+load 'title'
+plot   "run_queue" title "Run Queue" with line 3,\
+       "tape_queue" title "Tape Queue" with line 2,\
+       "finished"  title "Dumps Finished" with line 4,\
+       "bandw_free" title "Bandwidth Allocated" with line 8, \
+       "disk_alloc" title "%Disk Allocated" with line 1, \
+       "tape_wait" title "%Tape Wait" with line 5,\
+       "tape_idle" title "Taper Idle" with line 1,\
+       "dump_idle" title "Dumpers Idle" with line 4
diff --git a/amplot/amplot.sh.in b/amplot/amplot.sh.in
new file mode 100644 (file)
index 0000000..8ab4d20
--- /dev/null
@@ -0,0 +1,153 @@
+#!/bin/sh
+# Amanda, The Advanced Maryland Automatic Network Disk Archiver
+# Copyright (c) 1992-1998 University of Maryland at College Park
+# All Rights Reserved.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of U.M. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  U.M. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Author: Olafur Gudumundsson, (ogud@tis.com)  Trusted Information Systems
+# Formerly at:                   Systems Design and Analysis Group
+#                        Computer Science Department
+#                        University of Maryland at College Park
+#
+#      Amplot: a program to generate postscript plots of each nights amanda 
+#      performance 
+# 
+#      Author: Olafur Gudmundsson (ogud@tis.com) 
+#      Creation Date: April 1992 
+#      Last modified: April 1995 
+#      Input: list of amdumps 
+#      Output: Plot of amdump files as either gnuplots on the screen or
+#              Postscript files 
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+confdir=@CONFIG_DIR@
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:$PATH
+export PATH
+
+AWK=@AWK@
+AVARFLAG=@AWK_VAR_ASSIGNMENT_OPT@
+GNUPLOT=@GNUPLOT@
+COMPRESS=@AMPLOT_COMPRESS@
+
+if [ $# -eq 0 ] ; then
+       echo "Usage: $0 [-c] [-e] [-g] [-l] [-p] [-t hours] <amdump_files.[gz,z,Z]>"
+       echo "amplot generates plot for screen with fixed dimensions"
+       echo "  -c      Compress the input amdump files after plotting"
+       echo "  -e      Extends x (time) axes if needed"
+       echo "  -g      Run gnuplot directly no postscript file generated DEFAULT"
+       echo "  -l      Landscape mode suitable for printing"
+       echo "  -p      Postscript output (color)"
+       echo "  -b      The postscipt will be b/w"
+       echo "  -t T    Set the right edge of the plot to be T hours"
+       exit 1 
+fi
+
+tmp_files="bandw_free disk_alloc dump_idle finished run_queue tape_* title" 
+
+my_plot=$libexecdir/amplot.g
+paper=0 
+gnuplot=1
+cmpres=0
+para=""
+maxtime=4
+bw=0
+
+# setting up the parameters to pass to [gn]awk 
+while :; do 
+   case "$1" in
+   -c)  cmpres=1; shift;;
+   -e)  para=$para"$AVARFLAG extend=1 "; shift;;
+   -g)  gnuplot=1; shift;;
+   -l)  paper=1; para=$para"$AVARFLAG paper=1 "; shift;;
+   -p)  gnuplot=0; shift;;
+   -b) bw=1; shift;;
+   -t)  shift
+       if test "$#" -eq 0; then
+           echo "amplot: no argument for -t option" 1>&2
+           exit 5
+       fi
+       maxtime="$1"; shift;;
+   *) break;;
+   esac
+done
+if [ $# -eq 0 ] ; then 
+       echo "amplot: no input files" 1>&2
+       exit 5
+fi
+para=$para"$AVARFLAG maxtime=$maxtime"
+
+if [ $gnuplot  -eq 1 ] ; then
+       my_plot=$my_plot"p"             # use the plot prog that pauses
+       plot=" -geometry 800x700+40+0" 
+       para=$para"$AVARFLAG gnuplot=1 "
+       echo "Displaying graph on the screen, <CR> for next graph"
+
+       if [ "$paper" -eq 1 ] ; then
+               echo "amplot: -l requires -p flag at the same time" 1>&2
+               exit 6 
+       fi
+       if [ "$bw" -eq 1 ] ; then
+               echo "amplot: -b requires -p flag at the same time" 1>&2
+               exit 6 
+       fi
+fi
+
+if [ $bw -eq 1 ]; then
+       para=$para" bw=1"
+fi
+
+list="";               # files to compress at the end
+
+for i in ${1+"$@"}             # for all the input files
+do
+       f="$i";
+       if [ ! -f "$f" ] ; then 
+               f=`ls "$i" "$i".*[zZ] 2>/dev/null`
+       fi
+       if [ -f "$f" ] ; then           # found file 
+                disp=`$AWK -f $libexecdir/amcat.awk $AVARFLAG f="$f"`
+               if [ -z "$disp" ] ; then 
+                       echo "Do not know how to [gz|z]cat this file"
+               else
+                       /bin/rm -f $tmp_files 
+                       $disp "$f" | $AWK -f $libexecdir/amplot.awk $para
+                       $GNUPLOT $plot $my_plot
+                       if [ $disp = "cat" -a  $cmpres -eq 1 ] ; then
+                               list=$list" "$f
+                       fi
+               fi
+       else                            # check if file has been compressed
+               echo "No such file $i or $i.*[zZ]"
+       fi
+done
+
+/bin/rm -f $tmp_files 
+
+if [ "$list" != "" ] ; then            # now compress the files we worked on
+# comment out next line if you do not want compression at the end
+       echo "Compressing $list"
+       $COMPRESS $list
+fi
+exit 0
diff --git a/changer-src/Makefile.am b/changer-src/Makefile.am
new file mode 100644 (file)
index 0000000..68c186c
--- /dev/null
@@ -0,0 +1,71 @@
+# Makefile for Amanda tape changer programs.
+
+INCLUDES =             -I$(top_srcdir)/common-src -I$(top_srcdir)/server-src -I$(top_srcdir)/tape-src
+
+LIB_EXTENSION = la
+
+if WANT_CHIO_SCSI
+CHIO_SCSI = chg-scsi-chio
+endif
+
+if WANT_CHG_SCSI
+CHG_SCSI = chg-scsi
+endif
+
+libexec_PROGRAMS =     $(CHG_SCSI)
+EXTRA_PROGRAMS =       $(CHIO_SCSI)
+
+libexec_SCRIPTS =      chg-manual      chg-multi       chg-mtx         \
+                       chg-rth         chg-chs         chg-chio        \
+                       chg-zd-mtx      chg-juke        chg-rait        \
+                       chg-null        chg-mcutil      chg-disk        \
+                       chg-iomega
+
+###
+# 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) \
+       ../server-src/libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+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_chio_SOURCES = chg-scsi-chio.c scsi-hpux.c scsi-chio.c libscsi.h
+
+EXTRA_DIST = scsi-proto.c
+
+.pl:
+                       cat $< > $@
+                       chmod a+x $@
+                       -test -z "$(PERL)" || $(PERL) -c $@
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS) $(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
diff --git a/changer-src/Makefile.in b/changer-src/Makefile.in
new file mode 100644 (file)
index 0000000..7510aad
--- /dev/null
@@ -0,0 +1,701 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 tape changer programs.
+
+
+SOURCES = $(chg_scsi_SOURCES) $(chg_scsi_chio_SOURCES)
+
+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 = :
+host_triplet = @host@
+libexec_PROGRAMS = $(am__EXEEXT_2)
+EXTRA_PROGRAMS = $(am__EXEEXT_1)
+subdir = changer-src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+       $(srcdir)/chg-chio.pl.in $(srcdir)/chg-chs.sh.in \
+       $(srcdir)/chg-disk.sh.in $(srcdir)/chg-iomega.pl.in \
+       $(srcdir)/chg-juke.sh.in $(srcdir)/chg-manual.sh.in \
+       $(srcdir)/chg-mcutil.sh.in $(srcdir)/chg-mtx.sh.in \
+       $(srcdir)/chg-multi.sh.in $(srcdir)/chg-null.sh.in \
+       $(srcdir)/chg-rait.sh.in $(srcdir)/chg-rth.pl.in \
+       $(srcdir)/chg-zd-mtx.sh.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 = chg-manual.sh chg-multi.sh chg-mtx.sh chg-chs.sh \
+       chg-rth.pl chg-chio.pl chg-zd-mtx.sh chg-juke.sh chg-rait.sh \
+       chg-null.sh chg-mcutil.sh chg-disk.sh chg-iomega.pl
+@WANT_CHIO_SCSI_TRUE@am__EXEEXT_1 = chg-scsi-chio$(EXEEXT)
+@WANT_CHG_SCSI_TRUE@am__EXEEXT_2 = chg-scsi$(EXEEXT)
+am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libexecdir)"
+libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(libexec_PROGRAMS)
+am_chg_scsi_OBJECTS = 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)
+chg_scsi_OBJECTS = $(am_chg_scsi_OBJECTS)
+chg_scsi_LDADD = $(LDADD)
+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) \
+       scsi-chio.$(OBJEXT)
+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)
+libexecSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(libexec_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/chg-scsi-chio.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/chg-scsi.Po ./$(DEPDIR)/scsi-aix.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/scsi-bsd.Po ./$(DEPDIR)/scsi-cam.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/scsi-changer-driver.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/scsi-chio.Po ./$(DEPDIR)/scsi-hpux.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/scsi-hpux_new.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/scsi-irix.Po ./$(DEPDIR)/scsi-linux.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/scsi-solaris.Po ./$(DEPDIR)/sense.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(chg_scsi_SOURCES) $(chg_scsi_chio_SOURCES)
+DIST_SOURCES = $(chg_scsi_SOURCES) $(chg_scsi_chio_SOURCES)
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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_srcdir)/common-src -I$(top_srcdir)/server-src -I$(top_srcdir)/tape-src
+LIB_EXTENSION = la
+@WANT_CHIO_SCSI_TRUE@CHIO_SCSI = chg-scsi-chio
+@WANT_CHG_SCSI_TRUE@CHG_SCSI = chg-scsi
+libexec_SCRIPTS = chg-manual   chg-multi       chg-mtx         \
+                       chg-rth         chg-chs         chg-chio        \
+                       chg-zd-mtx      chg-juke        chg-rait        \
+                       chg-null        chg-mcutil      chg-disk        \
+                       chg-iomega
+
+
+###
+# 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) \
+       ../server-src/libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+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_chio_SOURCES = chg-scsi-chio.c scsi-hpux.c scsi-chio.c libscsi.h
+EXTRA_DIST = scsi-proto.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .pl .sh .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  changer-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  changer-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
+chg-manual.sh: $(top_builddir)/config.status $(srcdir)/chg-manual.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-multi.sh: $(top_builddir)/config.status $(srcdir)/chg-multi.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-mtx.sh: $(top_builddir)/config.status $(srcdir)/chg-mtx.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-chs.sh: $(top_builddir)/config.status $(srcdir)/chg-chs.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-rth.pl: $(top_builddir)/config.status $(srcdir)/chg-rth.pl.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-chio.pl: $(top_builddir)/config.status $(srcdir)/chg-chio.pl.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-zd-mtx.sh: $(top_builddir)/config.status $(srcdir)/chg-zd-mtx.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-juke.sh: $(top_builddir)/config.status $(srcdir)/chg-juke.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-rait.sh: $(top_builddir)/config.status $(srcdir)/chg-rait.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-null.sh: $(top_builddir)/config.status $(srcdir)/chg-null.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-mcutil.sh: $(top_builddir)/config.status $(srcdir)/chg-mcutil.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-disk.sh: $(top_builddir)/config.status $(srcdir)/chg-disk.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-iomega.pl: $(top_builddir)/config.status $(srcdir)/chg-iomega.pl.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+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
+chg-scsi$(EXEEXT): $(chg_scsi_OBJECTS) $(chg_scsi_DEPENDENCIES) 
+       @rm -f chg-scsi$(EXEEXT)
+       $(LINK) $(chg_scsi_LDFLAGS) $(chg_scsi_OBJECTS) $(chg_scsi_LDADD) $(LIBS)
+chg-scsi-chio$(EXEEXT): $(chg_scsi_chio_OBJECTS) $(chg_scsi_chio_DEPENDENCIES) 
+       @rm -f chg-scsi-chio$(EXEEXT)
+       $(LINK) $(chg_scsi_chio_LDFLAGS) $(chg_scsi_chio_OBJECTS) $(chg_scsi_chio_LDADD) $(LIBS)
+install-libexecSCRIPTS: $(libexec_SCRIPTS)
+       @$(NORMAL_INSTALL)
+       test -z "$(libexecdir)" || $(mkdir_p) "$(DESTDIR)$(libexecdir)"
+       @list='$(libexec_SCRIPTS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         if test -f $$d$$p; then \
+           f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+           echo " $(libexecSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(libexecdir)/$$f'"; \
+           $(libexecSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(libexecdir)/$$f"; \
+         else :; fi; \
+       done
+
+uninstall-libexecSCRIPTS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(libexec_SCRIPTS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+         echo " rm -f '$(DESTDIR)$(libexecdir)/$$f'"; \
+         rm -f "$(DESTDIR)$(libexecdir)/$$f"; \
+       done
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chg-scsi-chio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chg-scsi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-aix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-bsd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-cam.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-changer-driver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-chio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-hpux.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-hpux_new.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-irix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-linux.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scsi-solaris.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sense.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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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 -z "$$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) $(SCRIPTS)
+installdirs:
+       for dir in "$(DESTDIR)$(libexecdir)" "$(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:
+       -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-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-libexecPROGRAMS install-libexecSCRIPTS
+       @$(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-libexecPROGRAMS \
+       uninstall-libexecSCRIPTS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       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-info install-info-am \
+       install-libexecPROGRAMS install-libexecSCRIPTS 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-libexecPROGRAMS \
+       uninstall-libexecSCRIPTS
+
+
+.pl:
+                       cat $< > $@
+                       chmod a+x $@
+                       -test -z "$(PERL)" || $(PERL) -c $@
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS) $(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
+# 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/changer-src/chg-chio.pl.in b/changer-src/chg-chio.pl.in
new file mode 100644 (file)
index 0000000..fc25b3a
--- /dev/null
@@ -0,0 +1,473 @@
+#! @PERL@ -w
+
+# Catch for sh/csh on systems without #! ability.
+eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
+        & eval 'exec @PERL@ -S $0 $argv:q'
+                if 0;
+
+# 
+# This changer script controls tape libraries on operating systems that have a
+# chgio program
+#      DSL 7000 on FreeBSD is an example
+#
+# The changer being used is a n tape juke, that can be used with 1, n-1 or n
+# tapes in the juke. The special slot is slot n. The script does not
+# make assumptions about the number of slots, except that the special slot
+# is the highest number. The slot is special in the sense that it contains the
+# the only tape if the juke contains 1 tape and contains no tape if the juke
+# contains n-1 tapes. See getCurrentTape.
+#
+# Furthermore, the script uses drive 0 and assumes that the device is able to
+# figure itself how to move a type from slot m to drive 0 if asked to do so and
+# multiple pickers are present.
+#
+# The numbering of the slots is by the way from 1 to n with slots. The chio
+# program returns the slot numbers numbered from 0 to n-1 however.
+# 
+# This script is built up out of bits and pieces of the other scripts
+# and no credits are claimed. Most notably the chg-rth.pl script was used. That
+# script was written by Erik Frederick, <edf@tyrell.mc.duke.edu>.
+# 
+# Permission to freely use and distribute is granted (by me and was granted by
+# the original authors).
+#
+# Nick Hibma - nick.hibma@jrc.it
+#
+
+require 5.001;
+
+($progname = $0) =~ s#/.*/##;
+
+use English;
+use Getopt::Long;
+
+$| = 1;
+
+if (-d "@AMANDA_DBGDIR@") {
+       $logfile = "@AMANDA_DBGDIR@/changer.debug";
+} else {
+       $logfile = "/dev/null";
+}
+die "$progname: cannot open $logfile: $ERRNO\n"
+       unless (open (LOG, ">> $logfile"));
+
+#
+# get the information from the configuration file
+#
+
+$prefix="@prefix@";
+$prefix=$prefix;               # avoid warnings about possible typo
+$exec_prefix="@exec_prefix@";
+$exec_prefix=$exec_prefix;     # Ditto
+$sbindir="@sbindir@";
+if ( "@USE_VERSION_SUFFIXES@" eq "yes" ) {
+    $SUF = "-@VERSION@";
+} else {
+    $SUF = "";
+}
+
+chomp ($tapeDevice = `$sbindir/amgetconf$SUF tapedev 2>&1`);
+die "tapedev not found in amanda.conf"
+       if !$tapeDevice or $tapeDevice =~ m/BUGGY/;
+chomp ($changerDevice = `$sbindir/amgetconf$SUF changerdev 2>&1`);
+chomp $changerDevice;
+die "changerdev not found in amanda.conf"
+       if !$changerDevice or $changerDevice =~ m/BUGGY/;
+
+#
+# Initialise a few global variables
+#
+
+@slots = ();
+@drives = ();
+$max_slot = 0;
+$max_drive = 0;
+$nr_tapes = 0;
+
+@dow = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
+@moy = ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
+       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
+
+sub do_time {
+       my (@t);
+       my ($r);
+
+       ###
+       # Get the local time for the value.
+       ###
+
+       @t = localtime (time ());
+
+       ###
+       # Return the result.
+       ###
+
+       $r = sprintf "%s %s %2d %2d:%02d:%02d %4d",
+         $dow[$t[6]],
+         $moy[$t[4]],
+         $t[3],
+         $t[2], $t[1], $t[0],
+         1900 + $t[5];
+
+       return $r;
+}
+
+sub getCurrentTape {
+       print LOG &do_time(), ": enter: getCurrentTape\n";
+
+       #
+       # Determines the slot number for the tape that is currently in the
+       # drive. getTapeParams and getTapeStatus should have been called.
+       # If there is no tape in the drive, no current tape, 0 is returned.
+       #
+
+       my($slot, $i);
+
+       if ( !$drives[0] ) {            # drive empty
+               $i = 0;
+       } elsif ( $nr_tapes == 1 ) {    # one tape -> comes from slot max_slot
+               $i = $max_slot;
+       } else {                        # find first empty slot
+               $i = 0;
+               while ( $i < $#slots and $slots[$i] ) {
+                       $i++
+               }
+               $i++;
+       }
+
+       print LOG &do_time(), ": leave: getCurrentTape: $i\n";
+       return $i;
+}
+
+sub getTapeStatus {
+       print LOG &do_time(), ": enter: getTapeStatus\n";
+
+       #
+       # Sets $nr_tapes, @slots, @drives, $current_tape
+       #
+
+       my($type,$num,$status);
+
+       print LOG &do_time(), ": running: @CHIO@ -f $changerDevice status\n";
+       if ( !(open(FH,"@CHIO@ -f $changerDevice status|")) ) {
+               print "$progname: '@CHIO@ -f $changerDevice status' failed, $!\n";
+               exit(2);
+       }
+
+       #
+       # This routine requires the format of the output of 'chio status' to 
+       # be as follows:
+       #   picker 0: 
+       #   slot 0: <ACCESS>
+       #   slot 1: <ACCESS,FULL>
+       #   slot 2: <ACCESS,FULL>
+       #   (etc.)
+       #   drive 0: <ACCESS,FULL>
+
+
+       @slots=();
+       @drives=();
+
+       while( defined ($line = <FH>) ) {
+               chomp( $line );
+               print LOG &do_time(), ": $line\n";
+               next unless $line =~ m/(\w+)\s+(\d+):\s*<([^>]+)>/;
+               ($type,$num,$status) = ($1,$2,$3);
+               if ( $type =~ m/slot/i ) {
+                       $slots[$num] = ( $status =~ m/full/i ) ? 1 : 0;
+                       if ($slots[ $num ]) { $nr_tapes++ }
+               } elsif ( $type =~ m/drive/i ) {
+                       $drives[$num] = 0;
+                       if (  $status =~ m/full/i ) {
+                               $drives[$num] = 1;
+                               $nr_tapes++;
+                       }
+               } else {
+                       # ignore 'picker', empty ones, etc...
+               }
+       }
+       close(FH);
+
+       if ( $nr_tapes == 0 ) {
+               print "$progname: No tapes in changer!\n";
+               exit(2);
+       }
+
+       $currentTape = &getCurrentTape(); 
+
+       print LOG &do_time(), ": leave: getTapeStatus: $nr_tapes\n";
+       return($nr_tapes);
+}
+
+sub getTapeParams {
+       print LOG &do_time(), ": enter: getTapeParams\n";
+  
+       #
+       # Requests information on the number of slots, pickers and drives
+       # from the changer.
+       #
+
+       my($max_slot,$max_drive,$max_picker);
+  
+       print LOG &do_time(), ": running: @CHIO@ -f $changerDevice params\n";
+       if ( !open(FH,"@CHIO@ -f $changerDevice params|") ) {
+               print "$progname: '@CHIO@ -f $changerDevice params' failed, $!\n";
+               exit(2);
+       }
+  
+       #
+       # the format of the output of 'chio params' should be
+       #  /dev/ch0: 8 slots, 1 drive, 1 picker
+       #  /dev/ch0: current picker: 0
+       #
+
+       $max_slot = 0;
+       $max_picker = -1;
+       $max_drive = 0;
+
+       while( defined ($line = <FH>) ) {
+               chomp $line;
+               print LOG &do_time(), ": $line\n";
+               $max_slot       = $1 if $line =~ m/(\d+) slot/i;
+               $max_drive      = $1 if $line =~ m/(\d+) drive/i;
+               $max_picker     = $1 if $line =~ m/(\d+) picker/i;
+
+       }
+       close(FH);
+       if ( $max_drive == 0 or $max_picker == -1 ) {
+               print "$progname: No drive or picker ? ($max_drive/$max_picker)\n";
+               exit(2);
+       }
+
+       print LOG &do_time(), ": leave: getTapeParams: $max_slot, $max_drive, $max_picker\n";
+       return ($max_slot, $max_drive, $max_picker);
+}
+
+sub testTape {
+       my($tape) = @_;
+
+       #
+       # Check a few parameters to avoid the most serious problems
+       #
+
+       return
+               if $currentTape == $tape;
+
+       if( $slots[$tape-1] == 0 ) {
+               print "<none> $progname: no tape in slot requested\n";
+               exit(1);
+       }
+       if( $tape > $max_slot ) {
+               print $tape," $progname: requested a tape > $max_slot\n";
+               exit(2);
+       }
+       if( $tape < 1 ) {
+               print $tape," $progname: requested a tape < 1\n";
+               exit(2);
+       }
+       return;
+}
+
+sub Load {
+       my($tape) = @_;
+       print LOG &do_time(), ": enter: Load: $tape\n";
+
+       #
+       # Load tape $tape into drive 0
+       #
+
+       print LOG &do_time(), ": running: @CHIO@ -f $changerDevice move slot ", $tape - 1, " drive 0\n";
+       if ( system("@CHIO@ -f $changerDevice move slot ".($tape-1)." drive 0") ) {
+               print "$progname: cannot '@CHIO@ -f $changerDevice move' tape $tape into drive 0\n";
+               exit(2);
+       }
+       print LOG &do_time(), ": leave: Load\n";
+}
+
+sub Unload {
+       my($tape) = @_;
+       print LOG &do_time(), ": enter: Unload: $tape\n";
+
+       #
+       # Unload the tape from drive 0 and put it into the slot specified by
+       # $tape.
+       #
+
+       #
+       # Ecrix AutoPAK devices (based on the Spectra Logics 215 changer)
+       # can lock up if you try to move a tape from a drive to an open slot
+       # without first rewinding and ejecting the tape.  This appears to
+       # occur when the operation times out and the ch driver sends a device
+       # or bus reset. Ecrix claims this is about to be fixed with a new
+       # firmware rev but for now it's safest to just explicitly eject
+       # the tape before moving the cartridge.
+       #
+       if ( system ("@MT@ @MT_FILE_FLAG@ $tapeDevice offline") ) {
+               print "$progname: Warning, failed to eject the tape with '@MT@ @MT_FILE_FLAG@ $tapeDevice offline'\n";
+               # NB: not fatal; let chio try it's thing
+       }
+
+       if ( system("@CHIO@ -f $changerDevice move drive 0 slot ".($tape-1)." ") ) {
+               print "$progname: cannot '@CHIO@ -f $changerDevice move' tape $tape from drive 0\n";
+               exit(2);
+       }
+       print LOG &do_time(), ": leave: Unload\n";
+}
+
+sub changeTape {
+       my($tape) = @_;
+       print LOG &do_time(), ": enter: changeTape: $tape\n";
+
+       #
+       # Unload current tape and load a new tape from slot $tape.
+       #
+
+       if ($tape != $currentTape) {
+
+               &testTape($tape);
+
+               if( $currentTape != 0 ) {
+                       &Unload($currentTape);
+               }
+               &Load($tape);
+               $currentTape = $tape;
+       }
+       print LOG &do_time(), ": leave: changeTape\n";
+}
+
+
+#
+# Main program
+#
+
+#
+# Initialise
+#
+
+($max_slot, $max_drive) = &getTapeParams();
+
+$opt_slot = 0;                                 # perl -w fodder
+$opt_info = 0;                                 # perl -w fodder
+$opt_reset = 0;                                        # perl -w fodder
+$opt_eject = 0;                                        # perl -w fodder
+
+GetOptions("slot=s", "info", "reset", "eject"); 
+
+$nr_tapes = &getTapeStatus();
+
+#
+# Before we do anything with the tape changer we'll have to rewind the tape
+#
+
+if (-x "$sbindir/ammt$SUF") {
+       $MT="$sbindir/ammt$SUF";
+       $MTF="-f";
+} elsif (-x "@MT@") {
+       $MT="@MT@";
+       $MTF="@MT_FILE_FLAG@";
+} else {
+       print LOG &do_time(), ": mt program not found\n";
+       print "<none> mt program not found\n";
+       exit(1);
+}
+print LOG &do_time(), "MT -> $MT $MTF\n";
+
+system ("$MT $MTF $tapeDevice rewind")
+       unless $currentTape == 0;
+
+
+if ( $opt_slot ) {
+       if ( $opt_slot =~ /first/ ) {
+               &changeTape(1);
+               print LOG &do_time(), ": $currentTape $tapeDevice\n";
+               print "$currentTape $tapeDevice\n";
+       }
+       if ( $opt_slot =~ /last/ ) {
+               &changeTape($max_slot);
+               print LOG &do_time(), ": $currentTape $tapeDevice\n";
+               print "$currentTape $tapeDevice\n";
+       }
+       if ( $opt_slot =~ /current/ ) {
+               &changeTape($currentTape);
+               print LOG &do_time(), ": $currentTape $tapeDevice\n";
+               print "$currentTape $tapeDevice\n";
+       }
+       if ( $opt_slot =~ /next/ ) {
+               $tape = $currentTape+1;
+               if ( $tape > $max_slot ) {
+                       $tape = 1;
+               }
+               while ( $slots[$tape-1] == 0 ) {        # there is at least 1 
+                       if ( ++$tape > $max_slot ) {
+                               $tape = 1;
+                       }
+               }
+               &changeTape($tape);
+               print LOG &do_time(), ": $currentTape $tapeDevice\n";
+               print "$currentTape $tapeDevice\n";
+       }
+       if ( $opt_slot =~ /prev/ ) {
+               $tape = $currentTape-1;
+               if ( $tape < 1 ) {
+                       $tape = $max_slot;
+               }
+               while ( $slots[$tape-1] == 0 ) {        # there is at least 1
+                       if ( --$tape < 1 ) {
+                               $tape = $max_slot;
+                       }
+               }
+               &changeTape($tape);
+               print LOG &do_time(), ": $currentTape $tapeDevice\n";
+               print "$currentTape $tapeDevice\n";
+       }
+       if ( $opt_slot =~ /^\d+$/ ) {
+               &changeTape($opt_slot);
+               print LOG &do_time(), ": $currentTape $tapeDevice\n";
+               print "$currentTape $tapeDevice\n";
+       }
+       if ( $opt_slot =~ /advance/ ) {
+               $tape=$currentTape+1;
+               if ( $tape > $max_slot ) {
+                       $tape = 1;
+               }
+               if ( $currentTape ) { 
+                       &Unload($currentTape);
+               }
+               print LOG &do_time(), ": $currentTape $tapeDevice\n";
+               print "$currentTape , /dev/null\n";
+       }
+
+       exit 0;
+}
+
+if ( $opt_info ) {
+       if ( $currentTape == 0 ) {
+               &Load(1);                       # load random tape
+               $currentTape = 1;
+       }
+
+       print LOG &do_time(), ": $currentTape $max_slot 1\n";
+       print "$currentTape $max_slot 1\n";
+       exit 0;
+}
+
+if ( $opt_reset ) {
+       &changeTape(1);
+       print LOG &do_time(), ": $currentTape $tapeDevice\n";
+       print "$currentTape $tapeDevice\n";
+       exit 0;
+}
+
+if ( $opt_eject ) {
+       if ( $currentTape ) { 
+               &Unload($currentTape);
+               print "0 $tapeDevice\n";
+               exit 0;
+       } else {
+               print "$progname: drive was not loaded\n";
+               exit 1;
+       }
+}
+
+print "$progname: No command was received.  Exiting.\n";
+exit 1;
diff --git a/changer-src/chg-chs.sh.in b/changer-src/chg-chs.sh.in
new file mode 100644 (file)
index 0000000..063084b
--- /dev/null
@@ -0,0 +1,426 @@
+#!/bin/sh
+#
+# Amanda, The Advanced Maryland Automatic Network Disk Archiver
+# Copyright (c) 1991-1998 University of Maryland at College Park
+# All Rights Reserved.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of U.M. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  U.M. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Author: James da Silva, Systems Design and Analysis Group
+#                         Computer Science Department
+#                         University of Maryland at College Park
+#
+
+#
+# chg-chs.sh - chs tape changer script
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+pname="chg-chs"
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+if [ -d "@AMANDA_DBGDIR@" ]; then
+       logfile=@AMANDA_DBGDIR@/changer.debug
+else
+       logfile=/dev/null
+fi
+
+CHS=@CHS@
+
+if [ -x $sbindir/ammt$SUF ]; then
+       MT=$sbindir/ammt$SUF
+       MTF=-f
+elif [ -x "@MT@" ]; then
+       MT=@MT@
+       MTF=@MT_FILE_FLAG@
+else
+       answer="<none> $myname: mt program not found"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+echo MT "->" $MT $MTF >> $logfile
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+ourconf=`amgetconf$SUF changerfile`
+changerdev=`amgetconf$SUF changerdev`
+if test -n "$changerdev" && test x"$changerdev" != x/dev/null; then
+       CHS="$CHS -f$changerdev"
+fi
+
+# read in some config parameters
+
+if [ \! -f $ourconf ]; then
+       answer="<none> $pname: $ourconf does not exist"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+firstslot=`awk '$1 == "firstslot" {print $2}' $ourconf 2>/dev/null`
+if [ "$firstslot" = "" ]; then
+       answer="<none> $pname: firstslot not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+lastslot=`awk '$1 == "lastslot" {print $2}' $ourconf 2>/dev/null`
+if [ "$lastslot" = "" ]; then
+       answer="<none> $pname: lastslot not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+nslots=`expr $lastslot - $firstslot + 1`
+
+gravity=`awk '$1 == "gravity" {print $2}' $ourconf 2>/dev/null`
+if [ "$gravity" = "" ]; then
+       answer="<none> $pname: gravity not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+needeject=`awk '$1 == "needeject" {print $2}' $ourconf 2>/dev/null`
+if [ "$needeject" = "" ]; then
+       answer="<none> $pname: needeject not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+multieject=`awk '$1 == "multieject" {print $2}' $ourconf 2>/dev/null`
+if [ "$multieject" = "" ]; then
+       echo "Note -> multieject not specified in $ourconf" >> $logfile
+       multieject=0
+fi
+
+ejectdelay=`awk '$1 == "ejectdelay" {print $2}' $ourconf 2>/dev/null`
+if [ "$ejectdelay" = "" ]; then
+       echo "Note -> ejectdelay not specified in $ourconf" >> $logfile
+       ejectdelay=0
+fi
+
+ourstate=`awk '$1 == "statefile" {print $2}' $ourconf 2>/dev/null`
+if [ "$ourstate" = "" ]; then
+       answer="<none> $pname: statefile not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+# read in state: only curslot and curloaded at the present time
+
+curslot=`awk '$1 == "curslot" {print $2}' $ourstate 2>/dev/null`
+if [ "$curslot" = "" ]; then
+       curslot=$firstslot
+fi
+
+curloaded=`awk '$1 == "curloaded" {print $2}' $ourstate 2>/dev/null`
+if [ "$curloaded" = "" ]; then
+       curloaded=0
+fi
+
+
+# process the command-line
+
+# control vars to avoid code duplication: not all shells have functions!
+usage=0
+checkgravity=0
+ejectslot=0
+loadslot=0
+slotempty=0
+
+if [ $# -ge 1 ]; then command=$1; else command="-usage"; fi
+
+case "$command" in
+
+-info) # return basic information about changer
+
+       backwards=`expr 1 - $gravity`
+       answer="$curslot $nslots $backwards"
+       code=0
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+       ;;
+
+-reset) # reset changer
+
+       checkgravity=0
+       loadslot=1
+       newslot=$firstslot
+
+       # XXX put changer-specific reset here, if applicable
+       ;;
+
+-eject) # eject tape if loaded
+
+       checkgravity=0
+       loadslot=0
+       newslot=$curslot
+       ejectslot=1
+
+       if [ $curloaded -eq 0 ]; then
+               answer="$curslot $pname: slot already empty"
+               code=1
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+       ;;
+
+-slot) # change to slot
+
+       checkgravity=1
+       loadslot=1
+
+       slotparm=$2
+       case "$slotparm" in
+       [0-9]*) 
+               newslot=$slotparm
+               if [ \( $newslot -gt $lastslot \) -o \
+                    \( $newslot -lt $firstslot \) ]; then
+                       answer="$newslot $pname: no slot $newslot: legal range is $firstslot ... $lastslot"
+                       code=1
+                       echo "Exit -> $answer" >> $logfile
+                       echo "$answer"
+                       exit $code
+               fi
+               ;;
+       current)
+               newslot=$curslot
+               ;;
+       first)
+               newslot=$firstslot
+               ;;
+       last)
+               newslot=$lastslot
+               ;;
+       next|advance)
+               newslot=`expr $curslot + 1`
+               if [ $newslot -gt $lastslot ]; then
+                       newslot=$firstslot
+               fi
+               if [ $slotparm = advance ]; then
+                       loadslot=0
+               fi
+               ;;
+       prev)
+               newslot=`expr $curslot - 1`
+               if [ $newslot -lt $firstslot ]; then
+                       newslot=$lastslot
+               fi
+               ;;
+       *)
+               answer="<none> $pname: bad slot name \"$slotparm\""
+               code=1
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+               ;;
+       esac
+       ;;
+*)
+       usage=1
+       ;;
+esac
+
+
+if [ $usage -eq 1 ]; then
+       answer="<none> usage: $pname {-reset | -slot [<slot-number>|current|next|prev|advance]}"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+
+# check for legal move
+
+if [ \( $checkgravity -eq 1 \) -a \( $gravity -ne 0 \) ]; then
+       if [ \( $newslot -lt $curslot \) -o \( "$slotparm" = "prev" \) ]
+       then
+               answer="$newslot $pname: cannot go backwards in gravity stacker"
+               code=1
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+fi
+
+# get tape device name
+
+device=`awk '$1 == "slot" && $2 == '$newslot' {print $3}' $ourconf 2>/dev/null`
+if [ "$device" = "" ]; then
+       answer="$newslot $pname: slot $newslot device not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+# check if load needs an eject first
+
+if [ \( $needeject -eq 1 \) -a \( $loadslot -eq 1 \) -a \
+     \( $curloaded -eq 1 \) -a \( $newslot -ne $curslot \) ]; then
+       ejectslot=1
+fi
+
+
+if [ $ejectslot -eq 1 ]; then  # eject the tape from the drive
+
+       # XXX put changer-specific load command here, if applicable
+
+       curloaded=0             # unless something goes wrong
+       slotempty=0
+
+       # generically, first check that the device is there
+
+       if [ ! -c $device ]; then
+               answer="$newslot $pname: $device: not a device file"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+
+       # if multiple eject is required, do it now
+       if [ $multieject -eq 1 ]; then
+               loopslot=$curslot
+               while [ $loopslot -lt $newslot ]; do
+                       $MT $MTF $device offline >/dev/null 2>&1
+                       if [ $? -ne 0 ]; then
+                               answer="$newslot $pname: $device: unable to change slot $loopslot"
+                               code=2
+                               echo "Exit -> $answer" >> $logfile
+                               echo "$answer"
+                               exit $code
+                       fi
+                       loopslot=`/usr/bin/expr $loopslot + 1`
+               done
+       fi
+  
+       # second, try to unload the device
+       $MT $MTF $device offline >/dev/null 2>&1
+       $CHS deselect -d1 -s$curslot >/dev/null 2>&1
+       if [ $? -ne 0 ]; then
+               #
+               # XXX if the changer-specific eject command can distinguish
+               # betweeen "slot empty" and more serious errors, return 1
+               # for the first case, 2 for the second case.  Generically,
+               # we just presume an error signifies an empty slot.
+               #
+               #slotempty=1
+               answer="<none> $pname: tape unload to slot $curslot failed"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       else
+               sleep $ejectdelay
+       fi
+fi
+
+if [ \( $loadslot -eq 1 \) -a \( \( $curloaded -ne 1 \) -o \( \( $curloaded -eq 1 \) -a \( $newslot -ne $curslot \) \) \) ]; then      # load the tape from the slot
+
+       # XXX put changer-specific load command here, if applicable
+
+       curloaded=1             # unless something goes wrong
+       slotempty=0
+
+       # generically, first check that the device is there
+
+       if [ ! -c $device ]; then
+               answer="$newslot $pname: $device: not a device file"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+
+       $CHS select -s$newslot -d1 >/dev/null 2>&1
+       if [ $? -ne 0 ]; then
+               answer="<none> $pname: tape load from slot $newslot failed"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+       sleep 60
+
+       # second, try to rewind the device
+       $MT $MTF $device rewind >/dev/null 2>&1
+       if [ $? -ne 0 ]; then
+               #
+               # XXX if the changer-specific load command can distinguish
+               # betweeen "slot empty" and more serious errors, return 1
+               # for the first case, 2 for the second case.  Generically,
+               # we just presume an error signifies an empty slot.
+               #
+               slotempty=1
+               curloaded=0
+       fi
+fi
+
+# update state
+
+echo "# $pname state cache: DO NOT EDIT!"      >  $ourstate
+echo curslot $newslot                          >> $ourstate
+echo curloaded $curloaded                      >> $ourstate
+
+# return slot info
+
+if [ $slotempty -eq 1 ]; then
+       answer="<nonw> $pname: $newslot slot is empty"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+if [ "$command" = -slot -a "$slotparm" = advance ]; then
+       device=/dev/null
+fi
+
+answer="$newslot $device"
+code=0
+echo "Exit -> $answer" >> $logfile
+echo "$answer"
+exit $code
diff --git a/changer-src/chg-disk.sh.in b/changer-src/chg-disk.sh.in
new file mode 100644 (file)
index 0000000..1f0b851
--- /dev/null
@@ -0,0 +1,259 @@
+#! /bin/sh
+#
+# 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.
+#
+# Author: Jean-Christian SIMONETTI, System and Network Engineer
+#                                  Wanadoo Portails
+#                                  Sophia Antipolis, France
+#
+#      This changer script is based on a directory structure like:
+#      slot_root_dir -|
+#                     |- info
+#                     |- data -> slot1
+#                     |- slot1
+#                     |- slot2
+#                     |- ...
+#                     |- slotn
+#      where 'slot_root_dir' is the tapedev 'file:xxx' parameter and 'n'
+#      is the tapecycle parameter.
+#      
+#      To use this driver, just put the line 'tpchanger "chg-disk"' in your
+#      amanda.conf.
+#
+#      Example of use:
+#      --- cut here ---
+#      tapedev  "file:/BACKUP2/slots/"
+#      rawtapedev "file:/BACKUP2/slots/"
+#      changerdev "/dev/null"
+#      tpchanger "chg-disk"
+#      changerfile "/usr/local/amanda/etc/changer"
+#      tapetype HARD-DISK
+#      define tapetype HARD-DISK {
+#          length 12000 mbytes
+#      }
+#      --- cut here ---
+#
+#      The number of slot is equal to your tapecyle.
+#      You must create the slots and data directory.
+#
+
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+    SUF="-@VERSION@"
+else
+    SUF=
+fi
+
+MYNAME=$0
+
+TAPE=`amgetconf$SUF tapedev`
+SLOTDIR=`echo $TAPE | sed 's/^file://'`
+
+CHANGERFILE=`amgetconf$SUF changerfile`
+ACCESSFILE=$CHANGERFILE-access
+CLEANFILE=$CHANGERFILE-clean
+SLOTFILE=$CHANGERFILE-slot
+[ ! -f $ACCESSFILE ] && echo 0 > $ACCESSFILE
+[ ! -f $CLEANFILE ] && echo 0 > $CLEANFILE
+[ ! -f $SLOTFILE ] && echo 0 > $SLOTFILE
+ACCESSCOUNT=`cat $ACCESSFILE`
+CLEANCOUNT=`cat $CLEANFILE`
+
+FIRSTSLOT=1
+LASTSLOT=`amgetconf$SUF tapecycle`
+CURSLOT=0
+CLEANSLOT=$LASTSLOT
+
+load() {
+  WHICHSLOT=$1;
+  ln -s $SLOTDIR/slot$WHICHSLOT $SLOTDIR/data
+  echo $WHICHSLOT > $SLOTFILE
+}
+
+unload() {
+  rm -f $SLOTDIR/data
+  echo "0" > $SLOTFILE
+}
+
+readstatus() {
+  CURSLOT=`cat $SLOTFILE`
+}
+
+loadslot() {
+  WHICHSLOT=$1
+
+  case $WHICHSLOT in
+    [0-9]*) TYPE="digit";;
+    *) TYPE="string";;
+  esac
+
+  readstatus
+  NEWSLOT=0
+  if [ $WHICHSLOT = "current" ]; then
+    if [ $CURSLOT -le 0 ]; then
+      load $FIRSTSLOT
+      echo "$FIRSTSLOT $TAPE"
+      exit 0
+    else
+      echo "$CURSLOT $TAPE"
+      exit 0
+    fi
+  elif [ $WHICHSLOT = "next" -o $WHICHSLOT = "advance" ]; then
+    NEWSLOT=`expr $CURSLOT + 1`
+    [ $NEWSLOT -gt $LASTSLOT ] && NEWSLOT=$FIRSTSLOT
+  elif [ $WHICHSLOT = "prev" ]; then
+      NEWSLOT=`expr $CURSLOT - 1`
+      [ $NEWSLOT -lt $FIRSTSLOT ] && NEWSLOT=$LASTSLOT
+  elif [ $WHICHSLOT = "first" ]; then
+      NEWSLOT=$FIRSTSLOT
+  elif [ $WHICHSLOT = "last" ]; then
+      NEWSLOT=$LASTSLOT
+  elif [ $TYPE = "digit" ]; then
+    if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then
+      NEWSLOT=$WHICHSLOT
+    else
+      echo "0 illegal request"
+      exit 1
+    fi
+  elif [ $WHICHSLOT = "clean" ]; then
+    NEWSLOT=$CLEANSLOT
+  else
+    echo "0 illegal request"
+    exit 1
+  fi
+  if [ $NEWSLOT = $CURSLOT ]; then
+    echo "$CURSLOT $TAPE"
+    exit 0
+  fi
+  if [ $NEWSLOT = $CLEANSLOT ]; then
+    expr $CLEANCOUNT + 1 > $CLEANFILE
+    echo 0 > $ACCESSFILE
+  else
+    expr $ACCESSCOUNT + 1 > $ACCESSFILE
+    if [ $ACCESSCOUNT -gt $LASTSLOT ]; then
+      $MYNAME -slot clean >/dev/null
+    fi
+  fi
+
+  readstatus
+  if [ $CURSLOT -ne 0 ]; then
+    unload
+  fi
+
+  if [ $WHICHSLOT = "advance" ]; then
+    echo "$NEWSLOT /dev/null"
+    exit 0
+  fi
+  load $NEWSLOT
+  echo "$NEWSLOT $TAPE"
+  exit 0
+}
+
+info() {
+  readstatus
+  echo "$CURSLOT $LASTSLOT $FIRSTSLOT"
+  exit 0
+}
+
+reset() {
+  readstatus
+  [ $CURSLOT -gt 0 ] && unload
+  load $FIRSTSLOT
+  echo "$FIRSTSLOT $tape"
+  exit 0
+}
+
+eject() {
+  readstatus
+  if [ $CURSLOT -le 0 ]; then
+    echo "0 Drive was not loaded"
+    exit 1
+  else
+    unload
+    echo $CURSLOT
+    exit 0
+  fi
+}
+
+
+while [ $# -ge 1 ];do
+  case $1 in
+    -slot)
+           shift
+           loadslot $*
+           ;;
+    -clean)
+           shift
+           loadslot clean
+           ;;
+    -current)
+           shift
+           loadslot current
+           ;;
+    -next)
+           shift
+           loadslot next
+           ;;
+    -advance)
+           shift
+           loadslot advance
+           ;;
+    -prev)
+           shift
+           loadslot prev
+           ;;
+    -first)
+           shift
+           loadslot first
+           ;;
+    -last)
+           shift
+           loadslot last
+           ;;
+    -info)
+           shift
+           info
+           ;;
+    -reset)
+            shift
+            reset
+            ;;
+    -eject)
+            shift
+            eject
+            ;;
+    *)
+       echo "Unknown option $1"
+       exit 2
+       ;;
+  esac
+done
+
diff --git a/changer-src/chg-iomega.pl.in b/changer-src/chg-iomega.pl.in
new file mode 100644 (file)
index 0000000..6f946e0
--- /dev/null
@@ -0,0 +1,285 @@
+#! @PERL@ -w
+
+# Catch for sh/csh on systems without #! ability.
+eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
+        & eval 'exec @PERL@ -S $0 $argv:q'
+                if 0;
+
+# 
+# This changer script is designed for IOMEGA or JAZZ disks of various sizes
+# as well as any other removable disk media.
+#
+# This is a PURELY MANUAL changer. It requests insertion of disk media via
+# messages on /dev/tty. So it cannot be used via crontab.
+#
+# Make sure you comply with any of the following.
+# - Add statements 
+#         tpchanger "chg-iomega"
+#         tapedev "file:<mount_point_of_removable_disk>"
+#         # (e.g. tapedev "file:/mnt/iomega" )
+#         tapetype IOMEGA      
+#
+#         
+#         define tapetype IOMEGA {
+#             comment "IOMega 250 MB floppys"
+#             length 250 mbytes
+#             filemark 100 kbytes
+#             speed 1 mbytes
+#         }
+#   to your /etc/amanda/<backup_set>/amanda.conf file
+# - 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 a call to amlabel.
+# - Be aware 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.
+#
+# This script is built up out of bits and pieces of other scripts, in
+# particular chg-chio.pl. That script was written by 
+# Nick Hibma - nick.hibma@jrc.it
+# 
+# Permission to freely use and distribute is granted (by me and was granted by
+# the original authors).
+#
+# Christoph Pospiech <pospiech@de.ibm.com>
+#
+
+require 5.001;
+
+($progname = $0) =~ s#/.*/##;
+
+use English;
+use Getopt::Long;
+
+$| = 1;
+
+if (-d "@AMANDA_DBGDIR@") {
+       $logfile = "@AMANDA_DBGDIR@/changer.debug";
+} else {
+       $logfile = "/dev/null";
+}
+die "$progname: cannot open $logfile: $ERRNO\n"
+       unless (open (LOG, ">> $logfile"));
+
+
+#
+# get the information from the configuration file
+#
+
+$prefix="@prefix@";
+$prefix=$prefix;               # avoid warnings about possible typo
+$exec_prefix="@exec_prefix@";
+$exec_prefix=$exec_prefix;     # Ditto
+$sbindir="@sbindir@";
+if ( "@USE_VERSION_SUFFIXES@" eq "yes" ) {
+    $SUF = "-@VERSION@";
+} else {
+    $SUF = "";
+}
+
+chomp ($tapeDevice = `$sbindir/amgetconf$SUF tapedev 2>&1`);
+die "tapedev not found in amanda.conf"
+       if !$tapeDevice or $tapeDevice =~ m/BUGGY/;
+chomp ($changerDevice = `$sbindir/amgetconf$SUF changerdev 2>&1`);
+chomp $changerDevice;
+die "changerdev not found in amanda.conf"
+       if !$changerDevice or $changerDevice =~ m/BUGGY/;
+
+#
+# Initialise a few global variables
+#
+
+$current_label = "";
+$current_slot = 0;
+$max_slot = 1;
+
+@dow = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
+@moy = ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
+       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
+
+sub do_time {
+       my (@t);
+       my ($r);
+
+       ###
+       # Get the local time for the value.
+       ###
+
+       @t = localtime (time ());
+
+       ###
+       # Return the result.
+       ###
+
+       $r = sprintf "%s %s %2d %2d:%02d:%02d %4d",
+         $dow[$t[6]],
+         $moy[$t[4]],
+         $t[3],
+         $t[2], $t[1], $t[0],
+         1900 + $t[5];
+
+       return $r;
+}
+
+
+sub is_mounted {
+    my $device = shift @_;
+    my ($directory) = ($device =~ m/file\:(.*)$/);
+    if ( -d "$directory/data" ) { return 1;}
+    else {return 0;}
+}
+
+sub request {
+    my $label = shift @_;
+    my $answer;
+    open (TTY, "+</dev/tty") or die "Can't open tty.\n";
+    print TTY "Insert Disk with label $label\n";
+    read TTY,$answer,1;
+    close TTY;
+    return $answer;
+}
+
+sub print_label {
+    my $label = shift @_;
+    open (TTY, "+</dev/tty") or die "Can't open tty.\n";
+    print TTY "The current Disk has label $label\n";
+    close TTY;
+}
+
+sub get_label {
+    my $device = shift @_;
+    my ($directory) = ($device =~ m/file\:(.*)$/);
+    my @dir_list =  glob("$directory/data/*");
+    while ( ($_= shift(@dir_list)) ) {
+       if ( /0+\.([\w\d]+)/ ) {return $1;}
+    }
+    return "no label";
+}
+
+
+sub Load {
+    my $device = shift @_;
+    my ($directory) = ($device =~ m/file\:(.*)$/);
+    my $label;
+    print LOG &do_time(), ": enter: Load $device\n";
+    if ( ! &is_mounted($device) ) {
+       print LOG &do_time(), ": mounting $directory\n";
+       system "mount $directory";
+    }
+    $label = get_label $device;
+    &print_label($label);
+    print LOG &do_time(), ": current label: $label\n";
+    print LOG &do_time(), ": leave: Load\n";
+
+}
+
+sub Unload {
+    my $device = shift @_;
+    my ($directory) = ($device =~ m/file\:(.*)$/);
+    print LOG &do_time(), ": enter: Unload $device\n";
+    if ( &is_mounted($device) ) {
+       print LOG &do_time(), ": ejecting $directory\n";
+       system "eject $directory";
+    }
+    print LOG &do_time(), ": leave: Unload\n";
+}
+
+
+
+#
+# Main program
+#
+
+#
+# Initialise
+#
+
+
+$opt_slot = 0;                                 # perl -w fodder
+$opt_info = 0;                                 # perl -w fodder
+$opt_reset = 0;                                        # perl -w fodder
+$opt_eject = 0;                                        # perl -w fodder
+$opt_search = 0;                                       # perl -w fodder
+$opt_label = 0;                                        # perl -w fodder
+
+GetOptions("slot=s", "info", "reset", "eject", "search=s", "label=s"); 
+
+
+if ( $opt_slot ) {
+    print LOG &do_time(), ": Loading slot $opt_slot requested\n";
+    if ( ! &is_mounted ($tapeDevice) ) {
+       &request ("any");
+       &Load ($tapeDevice);
+    }
+    $current_label = &get_label ($tapeDevice);
+    print LOG &do_time(), ": current label: $current_label\n";
+    print LOG &do_time(), ": 1 $tapeDevice\n";
+    print "1 $tapeDevice\n";
+    exit 0;
+}
+
+if ( $opt_info ) {
+    print LOG &do_time(), ": info requested\n";
+    $current_label = &get_label ($tapeDevice);
+    print LOG &do_time(), ": current label: $current_label\n";
+    print LOG &do_time(), ": 1 $max_slot 1 1\n";
+    print "1 $max_slot 1 1\n";
+    exit 0;
+}
+
+if ( $opt_reset ) {
+    print LOG &do_time(), ": reset requested\n";
+    &Unload ($tapeDevice);
+    &request ("any");
+    &Load ($tapeDevice);
+    $current_label = &get_label ($tapeDevice);
+    print LOG &do_time(), ": current label: $current_label\n";
+    print LOG &do_time(), ": 1 $tapeDevice\n";
+    print "1 $tapeDevice\n";
+    exit 0;
+}
+
+if ( $opt_eject ) {
+    print LOG &do_time(), ": eject requested\n";
+    &Unload ($tapeDevice);
+    print LOG &do_time(), ": 1 $tapeDevice\n";
+    print "1 $tapeDevice\n";
+    exit 0;
+}
+
+if ( $opt_search ) {
+    print LOG &do_time(), ": search label $opt_search requested\n";
+    $retry = 0;
+    $current_label = &get_label ($tapeDevice);
+    print LOG &do_time(), ": current label: $current_label\n";
+    while ( $opt_search ne $current_label && ++$retry < 5) {
+       &Unload ($tapeDevice);
+       &request ($opt_search);
+       &Load ($tapeDevice);
+       $current_label = &get_label ($tapeDevice);
+       print LOG &do_time(), ": search label: $opt_search\n";
+       print LOG &do_time(), ": current label: $current_label\n";
+    }
+    if ( $retry >= 5) {
+       print LOG &do_time(), ": disk not found\n";
+       print "disk not found\n";
+       exit 1;
+    } else {
+       print LOG &do_time(), ": 1 $tapeDevice\n";
+       print "1 $tapeDevice\n";
+       exit 0;
+    }
+}
+
+if ( $opt_label ) {
+    print LOG &do_time(), ": label $opt_label requested\n";
+    # no operation
+    print LOG &do_time(), ": 1 $tapeDevice\n";
+    print "1 $tapeDevice\n";
+    exit 0;
+}
+
+print "$progname: No command was received.  Exiting.\n";
+exit 1;
diff --git a/changer-src/chg-juke.sh.in b/changer-src/chg-juke.sh.in
new file mode 100755 (executable)
index 0000000..abb0a1a
--- /dev/null
@@ -0,0 +1,266 @@
+#!/bin/sh
+
+# chg-juke
+#
+# This assumes we have possibly rait-striped drives in several
+# jukeboxes, controlled by the Fermilab "juke" package
+#
+# So we could have 3 drives in 3 jukeboxes:
+#   changerscript="chg-juke"
+#   changerfile=/some/file
+#   tapedev="rait:/dev/nst{1,2,3}"
+#   changerdev="myjuke{0,1,2}"
+# Or, if the jukebox has multiple drives:
+#   changerscript="chg-juke"
+#   changerfile=/some/file
+#   tapedev="rait:/dev/nst{1,2,3}"
+#   changerdev="myjuke"
+# We need therefore to generate lists with csh to expand the tapedev 
+# and changerdev, and deal with the possibility that there are several 
+# jukeboxes and several drives in each jukebox involved.
+
+#
+# debugging...
+#
+if [ -d "@AMANDA_DBGDIR@" ]; then
+       DBGFILE=@AMANDA_DBGDIR@/changer.debug
+else
+       DBGFILE=/dev/null
+fi
+exec 2>$DBGFILE
+echo "args: $0 $*" >&2
+set -x 
+
+#
+# the usual config fun
+#
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+MT=ammt
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+        SUF="-@VERSION@";
+else
+       SUF=
+fi
+getconf=$sbindir/amgetconf$SUF
+
+#
+# make sure we can find JUKE later
+#
+JUKE_DIR=/usr/local
+# Fermilab specific
+if [ -f /usr/local/etc/setups.sh ]
+then
+    . /usr/local/etc/setups.sh
+    setup juke
+fi
+
+PATH=$sbindir:$libexecdir:$JUKE_DIR/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH JUKE_DIR
+
+build_drivelists() {
+    #
+    # figure out which drives are in which jukebox
+    #
+    count=0
+    for juke in $jlist
+    do
+       for d in $dlist
+       do
+           if juke list -j $juke drive $d | grep 'drive [0-9]' >&2
+           then
+               eval "drives_in_$juke=\"\$drives_in_$juke $d\""
+           fi
+       done
+    done
+}
+
+unload_drive_n_clean() {
+
+    #
+    # $1 is whether to clean it
+    #
+    cleanit=$1
+
+    #
+    # if the drive is ONLINE, mt unload it
+    #
+    if $MT -t $tapedev status | egrep "$ONLINEREGEX" >&2
+    then
+       $MT -t $tapedev offline >&2 || true
+    fi
+
+    #
+    # unload any tapes present, maybe load/unload a cleaning cartridge
+    #
+    for juke in $jlist
+    do
+       eval "jdlist=\"\$drives_in_$juke\""
+       for drive in $jdlist
+       do
+           juke unload -j $juke drive $drive >&2 || true
+           if juke list -j $juke drive $drive | grep '(empty)' >&2
+           then
+               :
+           else
+               echo "$slot $tapedev unable to empty preceding tape from drive $drive"
+               exit 1
+           fi
+
+           if $cleanit
+            then
+                juke load -j $juke drive $drive clean
+               sleep 120
+                juke unload -j $juke drive $drive
+            fi
+       done
+    done
+}
+
+load_drives() {
+    #
+    # load slots.  If it's a stripe, load several...
+    #
+    for juke in $jlist
+    do
+       eval "jdlist=\"\$drives_in_$juke\""
+       jndrives=`echo $jdlist | wc -w`
+       count=0
+       for drive in $jdlist
+       do
+           rslot=`expr $newslot '*' $jndrives + $count`
+           juke load -j $changerdev drive $drive slot $rslot >&2
+           if juke list -j $changerdev drive $drive | grep '(empty)' >&2
+           then
+               echo "$slot $tapedev unable to load tape into drive"
+               exit 1
+           fi
+           count=`expr $count + 1`
+       done
+    done
+
+    #
+    # wait for drive(s) to come online
+    #
+    count=0
+    until  $MT -t $tapedev status | egrep "$ONLINEREGEX" >&2
+    do
+       count=`expr $count + 1`
+       if [ $count -gt 24 ] 
+       then
+           echo "$slot $tapedev never came online"
+           exit 1
+       fi
+       sleep 5
+    done
+}
+
+
+ONLINEREGEX="ONLINE|READY|sense[_ ]key[(]0x0[)]|sense key error = 0|^er=0$"
+
+#
+# get config variables
+#
+changerfile=`$getconf changerfile`
+    tapedev=`$getconf tapedev`
+ changerdev=`$getconf changerdev`
+      dlist=`csh -c "echo $tapedev" | sed -e 's/rait://g' -e 's/tape://g'`
+    ndrives=`echo $dlist | wc -w`
+      jlist=`csh -c "echo $changerdev"`
+     njukes=`echo $jlist | wc -w`
+ totalslots=`for juke in $jlist ; do juke list -j $juke; done | 
+               grep -v '^clean' | 
+               grep 'slot [0-9]' | 
+               wc -l`
+
+if [ $ndrives -gt 1 ]
+then
+   #
+   # if it's a 3 tape stripe and we have 30 actual slots
+   # we only have 10 virtual slots...
+   #
+   totalslots=`expr $totalslots / $ndrives`
+fi
+
+build_drivelists
+
+#
+# get current slot if we have one
+#
+if [ -f "$changerfile" ] 
+then
+    slot="`cat $changerfile`"
+else
+    slot=0
+    echo $slot > $changerfile
+fi
+
+#
+# We treat -reset just like -slot 0
+#
+if [ x$1 = 'x-reset' ]
+then
+    set : -slot 0
+    shift
+fi
+
+case x$1 in
+
+x-slot) 
+
+    #
+    # handle special slots...
+    #
+    case "$2" in
+    current)   newslot=$slot           ; load=true;;
+    next)      newslot=`expr $slot + 1`; load=true;;
+    advance)   newslot=`expr $slot + 1`; load=false;;
+    prev)      newslot=`expr $slot - 1`; load=true;;
+    first)     newslot=0               ; load=true;;
+    last)      newslot=-1              ; load=true;;
+    *)         newslot=$2              ; load=true;;
+    esac
+
+    if [ $newslot = "clean" ]
+    then
+       unload_drive_n_clean true
+    else 
+       if [ 0 -gt $newslot ]
+       then
+           newslot=`expr $totalslots - 1`
+       fi
+
+       if [ $totalslots -le  $newslot ]
+       then
+           newslot=0
+       fi
+
+       echo $newslot > $changerfile
+       slot=$newslot
+
+       if $load
+       then
+           unload_drive_n_clean false
+           load_drives
+       fi
+    fi
+
+    echo $slot $tapedev
+    ;;
+
+x-info)
+    echo $slot $totalslots 1
+    exit 0
+    ;;
+
+x-eject)
+    unload_drive_n_clean false
+    echo $slot $tapedev
+    ;;
+esac
+
+exit $rc
diff --git a/changer-src/chg-manual.sh.in b/changer-src/chg-manual.sh.in
new file mode 100644 (file)
index 0000000..0c966d4
--- /dev/null
@@ -0,0 +1,310 @@
+#!/bin/sh 
+#
+# Exit Status:
+# 0 Alles Ok
+# 1 Illegal Request
+# 2 Fatal Error
+#
+
+# try to hit all the possibilities here
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+if [ -d "@AMANDA_DBGDIR@" ]; then
+       logfile=@AMANDA_DBGDIR@/changer.debug
+else
+       logfile=/dev/null
+fi
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+myname=$0
+
+EGREP='@EGREP@'
+
+if [ -x $sbindir/ammt$SUF ]; then
+       MT=$sbindir/ammt$SUF
+       MTF=-f
+elif [ -x "@MT@" ]; then
+       MT=@MT@
+       MTF=@MT_FILE_FLAG@
+else
+       answer="<none> $myname: mt program not found"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+echo MT "->" $MT $MTF >> $logfile
+
+if [ -x $sbindir/amdd$SUF ]; then
+       DD=$sbindir/amdd$SUF
+elif [ -x "@DD@" ]; then
+       DD=@DD@
+else
+       answer="<none> $myname: dd program not found"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+echo DD "->" $DD >> $logfile
+
+MAILER=@MAILER@
+ONLINEREGEX="ONLINE|READY|sense[_ ]key[(]0x0[)]|sense key error = 0|^er=0$|, mt_erreg: 0x0|^Current Driver State: at rest$"
+REPORTTO=`amgetconf$SUF mailto`
+tape=`amgetconf$SUF tapedev`
+ORG=`amgetconf$SUF ORG`
+
+firstslot=1
+lastslot=99
+
+changerfile=`amgetconf$SUF changerfile`
+
+cleanfile=$changerfile-clean
+accessfile=$changerfile-access
+slotfile=$changerfile-slot
+[ ! -f $cleanfile ] && echo 0 > $cleanfile
+[ ! -f $accessfile ] && echo 0 > $accessfile
+[ ! -f $slotfile ] && echo $firstslot > $slotfile
+cleancount=`cat $cleanfile`
+accesscount=`cat $accessfile`
+slot=`cat $slotfile`
+
+request() {
+       echo "insert tape into slot $1 and press return" >/dev/tty
+       read ANSWER </dev/tty
+}
+
+###
+# If $changerfile exists, source it into this script.  One reason is to
+# override the request() function above which gets called to request
+# that a tape be mounted.  Here is an alternate versions of request()
+# that does things more asynchronous:
+#
+#  request() {
+#      # Send E-mail about the mount request and wait for the drive
+#      # to go ready by checking the status once a minute.  Repeat
+#       # the E-mail once an hour in case it gets lost.
+#      timeout=0
+#      while true;do
+#          if [ $timeout -le 0 ]; then
+#              echo "insert Amanda tape into slot $1 ($tape)" \
+#                | $MAILER -s "$ORG AMANDA TAPE MOUNT REQUEST FOR SLOT $1" \
+#                        $REPORTTO
+#              timeout=`expr 60 \* 60`
+#          fi
+#          echo "     -> rewind $tape" >> $logfile
+#          $MT $MTF $tape rewind >> $logfile 2>&1
+#          echo "     -> status $tape" >> $logfile
+#          used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
+#          echo "     -> loaded <$used>" >> $logfile
+#          if [ ! -z "$used" ];then
+#              break
+#          fi
+#          sleep 60
+#          timeout=`expr $timeout - 60`
+#      done
+#  }
+#
+# Instead of sending mail, you might write the message to /dev/console
+# or use "logger" to send it via syslog, etc.
+###
+
+if [ -f $changerfile ]; then
+       . $changerfile
+fi
+
+#
+
+eject() { 
+       echo "     -> rewind $tape" >> $logfile
+       $MT $MTF $tape rewind >> $logfile 2>&1
+       echo "     -> status $tape" >> $logfile
+       used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
+       echo "     -> loaded <$used>" >> $logfile
+       if [ ! -z "$used" ];then
+               echo "     -> offline $tape" >> $logfile
+               $MT $MTF $tape offline >> $logfile 2>&1
+               echo 0 > $slotfile
+               answer="$slot $tape"
+               code=0
+       else
+               answer="<none> $myname: Drive was not loaded"
+               code=1
+       fi
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+}
+
+#
+
+reset() {
+       echo "     -> rewind $tape" >> $logfile
+       $MT $MTF $tape rewind >> $logfile 2>&1
+       echo "     -> status $tape" >> $logfile
+       used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
+       echo "     -> loaded <$used>" >> $logfile
+       if [ ! -z "$used" ];then
+               answer="$slot $tape"
+       else
+               answer="0 $tape"
+       fi
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit 0
+}
+
+# load #
+
+loadslot() {
+       echo "     -> rewind $tape" >> $logfile
+       $MT $MTF $tape rewind >> $logfile 2>&1
+       echo "     -> status $tape" >> $logfile
+       used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
+       echo "     -> loaded <$used>" >> $logfile
+       whichslot=$1
+       case $whichslot in
+       current)
+               load=$slot
+               [ $load -eq 0 ] && load=$firstslot
+               [ $load -gt $lastslot ] && load=$firstslot
+               [ $load -lt $firstslot ] && load=$lastslot
+               ;;
+       next|advance)
+               load=`expr $slot + 1`
+               [ $load -gt $lastslot ] && load=$firstslot
+               ;;
+       prev)
+               load=`expr $slot - 1`
+               [ $load -lt $firstslot ] && load=$lastslot
+               ;;
+       first)
+               load=$firstslot
+               ;;
+       last)
+               load=$lastslot
+               ;;
+       [0-9]|[0-9][0-9])
+               if [ $1 -lt $firstslot -o $1 -gt $lastslot ]; then
+                       answer="<none> $myname: slot must be $firstslot .. $lastslot"
+                       echo "Exit -> $answer" >> $logfile
+                       echo "$answer"
+                       exit 1
+               fi
+               load=$1
+               ;;
+       *)
+               answer="<none> $myname: illegal slot: $1"
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit 1
+               ;;
+       esac
+       #
+       if [ ! -z "$used" -a $load = $slot ];then
+               # already loaded
+               answer="$slot $tape"
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit 0
+       fi
+
+       # if [ $load = $ecleanslot ]; then
+       # expr $cleancount + 1 > $cleanfile
+       # echo 0 > $accessfile
+       # else
+       expr $accesscount + 1 > $accessfile
+       # if [ $accesscount -gt 9 ]; then
+       # $myname -slot $cleanslot >/dev/null
+       # used=0
+       # fi
+       # fi    
+
+       #
+       if [ ! -z "$used" ]; then
+               echo "     -> offline $tape" >> $logfile
+               $MT $MTF $tape offline >> $logfile 2>&1
+               used=""
+       fi
+       if [ $whichslot = advance ]; then
+               tape=/dev/null
+       else
+               echo "     -> load   $load" >> $logfile
+               while [ -z "$used" ]; do
+                       request $load
+                       echo "     -> rewind $tape" >> $logfile
+                       $MT $MTF $tape rewind >> $logfile 2>&1
+                       echo "     -> status $tape" >> $logfile
+                       used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
+                       echo "     -> loaded <$used>" >> $logfile
+               done
+               $DD if=$tape bs=32k count=1 >> $logfile 2>&1
+       fi
+       echo $load > $slotfile
+       answer="$load $tape"
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit 0
+}
+
+#
+
+info() {
+       echo "     -> rewind $tape" >> $logfile
+       $MT $MTF $tape rewind >> $logfile 2>&1
+       echo "     -> status $tape" >> $logfile
+       used=`$MT $MTF $tape status 2>&1 | tee -a $logfile | $EGREP "$ONLINEREGEX"`
+       echo "     -> loaded <$used>" >> $logfile
+       if [ -z "$used" ];then
+               answer="0 $lastslot 1"
+       else
+               answer="$slot $lastslot 1"
+       fi
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit 0
+}
+
+#
+# main part
+#
+
+echo Args "->" "$@" >> $logfile
+while [ $# -ge 1 ];do
+       case $1 in
+       -slot)
+               shift
+               loadslot $*
+               ;;
+       -info)
+               shift
+               info
+               ;;
+       -reset)
+               shift
+               reset
+               ;;
+       -eject)
+               shift
+               eject
+               ;;
+       *)
+               echo "<none> $myname: Unknown option $1"
+               exit 2
+               ;;
+       esac
+done
+
+exit 0
diff --git a/changer-src/chg-mcutil.sh.in b/changer-src/chg-mcutil.sh.in
new file mode 100644 (file)
index 0000000..934e2f7
--- /dev/null
@@ -0,0 +1,564 @@
+#!/bin/sh 
+#
+# Author: Robert Dege
+#
+#
+# version 1.2
+# -----------
+# fixed last_cleaned file so that if it doesn't exist, it gets created with current date, not '0,0'
+# fixed a bug that was reporting the wrong slot # to amcheck
+#
+# version 1.1
+# -----------
+# amverify was failing when using -slot current.  Fixed exit $code from 1 -> 0.
+# removed useless $current variables from movetape() function.
+#
+#
+#
+# Exit Status:
+# 0 Alles Ok
+# 1 Illegal Request
+# 2 Fatal Error
+#
+
+
+#
+# Set Path so that it includes Amanda binaries, and access to tapechanger & drive programs
+#
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin
+export PATH
+
+
+#
+# Define Suffix for amanda binaries
+#
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+        SUF="-@VERSION@"
+else
+        SUF=
+fi
+
+
+#
+# Load configuration data from the config file
+#
+
+ourconf=`amgetconf$SUF changerfile`
+myname=$0
+
+
+if [ ! -f "$ourconf" ]; then
+        code=2
+        echo "Command Line -> $myname $@\nExit($code): $ourconf not found as listed in amanda.conf"
+        exit $code
+fi
+
+
+# grab mcutil info
+tmpval1=`grep ^mcutil $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^mcutil $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): mcutil not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       MCUTIL=$tmpval2
+else
+       MCUTIL=$tmpval1
+fi
+
+
+# grab tape info
+tmpval1=`grep ^tape $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^tape $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): tape not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       tape=$tmpval2
+else
+       tape=$tmpval1
+fi
+
+
+# grab firstslot info
+tmpval1=`grep ^firstslot $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^firstslot $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+        code=2
+        echo "Command Line -> $myname $@ \nExit($code): firstslot not specified in $ourconf"
+        exit $code
+elif [ -z "$tmpval1" ]; then
+        firstslot=$tmpval2
+else
+        firstslot=$tmpval1
+fi
+
+
+# grab lastslot info
+tmpval1=`grep ^lastslot $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^lastslot $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+        code=2
+        echo "Command Line -> $myname $@ \nExit($code): lastslot not specified in $ourconf"
+        exit $code
+elif [ -z "$tmpval1" ]; then
+        lastslot=$tmpval2
+else
+        lastslot=$tmpval1
+fi
+
+
+# grab use_cleaning info
+tmpval1=`grep ^use_cleaning $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^use_cleaning $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+        code=2
+        echo "Command Line -> $myname $@ \nExit($code): use_cleaning not specified in $ourconf"
+        exit $code
+elif [ -z "$tmpval1" ]; then
+        use_cleaning=$tmpval2
+else
+        use_cleaning=$tmpval1
+fi
+
+
+# grab cleanslot info
+tmpval1=`grep ^cleanslot $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^cleanslot $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+        code=2
+        echo "Command Line -> $myname $@ \nExit($code): cleanslot not specified in $ourconf"
+        exit $code
+elif [ -z "$tmpval1" ]; then
+        cleanslot=$tmpval2
+else
+        cleanslot=$tmpval1
+fi
+
+
+# grab cleansleep info
+tmpval1=`grep ^cleansleep $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^cleansleep $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): cleansleep not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       cleansleep=$tmpval2
+else
+       cleansleep=$tmpval1
+fi
+
+
+# grab cleanme info
+tmpval1=`grep ^cleanme $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^cleanme $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): cleanme not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       cleanme=$tmpval2
+else
+       cleanme=$tmpval1
+fi
+
+
+# grab cleanfile info
+tmpval1=`grep ^cleanfile $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^cleanfile $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+        code=2
+        echo "Command Line -> $myname $@ \nExit($code): cleanfile not specified in $ourconf"
+        exit $code
+elif [ -z "$tmpval1" ]; then
+        cleanfile=$tmpval2
+else
+        cleanfile=$tmpval1
+fi
+
+
+# grab lastfile info
+tmpval1=`grep ^lastfile $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^lastfile $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): lastfile not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       lastfile=$tmpval2
+else
+       lastfile=$tmpval1
+fi
+
+
+# grab currentslot info
+tmpval1=`grep ^currentslot $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^currentslot $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): currentslot not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       currentslot=$tmpval2
+else
+       currentslot=$tmpval1
+fi
+
+
+# grab logfile info
+tmpval1=`grep ^logfile $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^logfile $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): logfile not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       logfile=$tmpval2
+else
+       logfile=$tmpval1
+fi
+
+[ ! -w $logfile ] && logfile=/dev/null
+
+
+# grab slot0source info
+tmpval1=`grep ^slot0source $ourconf | awk -F\  '{print $2}'`
+tmpval2=`grep ^slot0source $ourconf | awk -F= '{print $2}'`
+if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
+       code=2
+       echo "Command Line -> $myname $@ \nExit($code): slot0source not specified in $ourconf"
+       exit $code
+elif [ -z "$tmpval1" ]; then
+       slot0source=$tmpval2
+else
+       slot0source=$tmpval1
+fi
+
+
+
+#
+# Verify currentslot contains a value
+#
+if [ ! -f $currentslot ] || [ `cat $currentslot` -lt $firstslot ];then
+   readstatus
+   echo $used > $currentslot
+fi
+
+current=`cat $currentslot`
+
+
+# Start logging to $logfile
+echo "\n\n==== `date` ====" >> $logfile
+echo "Command Line -> $myname $@" >> $logfile
+
+
+#
+# is Use Cleaning activated?
+#
+if [ $use_cleaning -eq 1 ]; then
+   curday=`date +%j`
+   curyear=`date +%Y`
+
+   [ ! -f $cleanfile ] && echo 0 > $cleanfile
+   [ ! -f $lastfile ] && echo $curday,$curyear > $lastfile
+
+
+#
+# Check to see when tape drive was last cleaned
+# output warning message if it's been too long
+# Currently, if it's been more than 45days, then
+# an error message is displayed everytime the
+# script is called, until the clean parameter
+# is run
+#
+   cleaned=`cat $cleanfile`
+   lastcleaned=`cut -d, -f1 $lastfile`
+   yearcleaned=`cut -d, -f2 $lastfile`
+
+  if [ `expr $curday - $lastcleaned`  -lt 0 ];then
+     diffday=`expr $curday - $lastcleaned + 365`
+     diffyear=`expr $curyear - $yearcleaned - 1`
+  else
+     diffday=`expr $curday - $lastcleaned`
+     diffyear=`expr $curyear - $yearcleaned`
+  fi
+
+  if [ $diffday -gt $cleanme ] || [ $diffyear -ge 1 ];then
+     if [ $diffyear -ge 1 ];then
+         echo "Warning, it's been $diffyear year(s) & $diffday days since you last cleaned the tape drive!"
+     else
+         echo "Warning, it's been $diffday days since you last cleaned the tape drive!"
+     fi
+  fi
+
+fi
+
+
+#
+# Read if there is a tape in the tape drive
+# If so, determine what slot is the tape from
+#
+readstatus() {
+  echo -n "querying tape drive....." >> $logfile
+  used=`expr \`$MCUTIL -e drive | tr = \] | cut -d\] -f2\` - $slot0source`
+  echo " Done" >> $logfile
+
+  # Give changer a chance to reset itself
+  sleep 3
+}
+
+
+#
+# If tape is in the drive, eject it
+#
+eject() {
+  echo "tape drive eject was called" >> $logfile
+
+  readstatus 
+
+  if [ $used -ge $firstslot ];then
+    $MCUTIL -m drive slot:$used
+    code=$?
+  else
+    code=1
+  fi
+
+  if [ $code -eq 0 ];then
+    answer="Cartridge $used successfully ejected from $tape"
+    echo "Exit($code): $answer" >> $logfile
+    echo $current $tape                #For amtape output  
+    return $code
+  elif [ $code -eq 1 ];then
+    answer="No Cartridge in Tape Drive"
+    echo "Exit($code): $answer" >> $logfile
+    echo $current $answer      #For amtape output
+    exit $code
+  else
+    answer="Tape abnormally failed"
+    echo "Exit($code): $answer" >> $logfile
+    echo $current $answer      #For amtape output
+    exit $code
+  fi
+}
+
+
+#
+# reset tape drive to a current state.
+# This involves ejecting the current tape (if occupied)
+# and inserting the tape in $firstslot
+#
+reset() {
+  echo "tape drive reset was called" >> $logfile
+
+  readstatus
+
+  if [ $used -ge $firstslot ];then
+     eject
+  fi
+
+  res=`$MCUTIL -m slot:$firstslot drive`
+  code=$?
+
+
+  if [ $code -eq 0 ];then
+    echo $firstslot > $currentslot
+    answer="$firstslot - Tape drive was successfully reset"
+  elif [ $code -eq 1 ];then
+    answer="$firstslot - Tape drive reset failed\nCommand -> $res"
+  else
+    code=2
+    answer="$firstlot - Tape abnormally failed -> $res"
+  fi
+
+  echo "Exit($code): slot $answer" >> $logfile
+  echo $firstslot      #For amtape output 
+  exit $code
+}
+
+
+
+
+#
+# Load a specific cartridge into the changer
+#
+loadslot() {
+  echo "loadslot was called" >> $logfile
+
+  readstatus
+
+  whichslot=$1
+
+  case $whichslot in
+    current)
+       if [ $current -ge $firstslot ];then
+          load=$current
+       else
+          load=$used
+       fi
+
+       movetape
+       ;;
+    next|advance)
+         [ $used -lt $firstslot ] && used=$current
+
+         load=`expr $used + 1`
+         [ $load -gt $lastslot ] && load=$firstslot
+
+         if [ $whichslot = advance ];then
+            echo $load > $currentslot
+            code=0
+            answer="advancing to slot $load"
+            echo "Exit($code): $answer" >> $logfile
+            echo $load $code
+            exit $code
+         else
+            movetape
+         fi
+         ;;
+    prev)
+         [ $used -lt $firstslot ] && used=$current
+
+         load=`expr $used - 1`
+         [ $load -lt $firstslot ] && load=$lastslot
+         movetape
+         ;;
+    first)
+         load=$firstslot
+         movetape
+         ;;
+    last)
+         load=$lastslot
+         movetape
+         ;;
+    [$firstslot-$lastslot])
+            load=$1
+            movetape
+         ;;
+    clean)
+         if [ use_cleaning -eq 1 ];then
+            current=$cleanslot
+            eject
+            $MCUTIL slot:$cleanslot drive
+            sleep $cleansleep
+            echo "$curday,$curyear" > $lastfile
+            echo `expr $cleaned + 1` > $cleanfile
+            reset
+         else
+            code=1
+            answer="Cleaning not enabled in config" >> $logfile
+            echo "Exit($code): $answer" >> $logfile
+            echo $cleanslot $answer
+            exit $code
+         fi
+         ;;
+    *)
+       code=1
+       answer="\"$whichslot\" invalid menu option"
+       echo "Exit($code): slot $answer" >> $logfile
+       echo "$answer"
+       exit $code
+       ;;
+    esac
+}
+
+
+#
+# sub-function that slot calls to actually eject the tape
+# & load in the correct slot cartridge
+#
+movetape() {
+
+    # If the requested slot is already loaded in the tape drive
+    if [ $load -eq $used ]; then
+        code=0
+       answer="$load is already loaded"
+        echo "Exit($code): slot $answer" >> $logfile
+        echo $load $tape       # For amtape output
+        exit $code
+    elif [ $used -ge $firstslot ];then
+       current=$load
+       eject
+    else
+       echo $load $tape        # For amtape output
+    fi
+
+    echo "Loading slot $load into Tape drive" >> $logfile
+    $MCUTIL -m  slot:$load drive
+    code=$?
+
+    if [ $code -eq 0 ];then
+       echo $load > $currentslot
+       answer="Cartridge $load successfully loaded in Tape drive"
+    else
+       answer="Cartridge $load failed to load in Tape drive"
+    fi
+       echo "Exit($code): $answer" >> $logfile
+       exit $code
+}
+
+
+info() {
+  echo "tape drive info was called" >> $logfile
+
+  readstatus
+
+  if [ $used -lt 0 ];then
+    used=0
+  fi
+
+  code=0
+  answer="$used $lastslot 1"
+  echo "Exit($code): $answer" >> $logfile
+  echo "$answer"
+  exit $code
+}
+
+
+  case $1 in
+    -slot)
+          shift
+          loadslot $*
+          ;;
+    -device)
+          echo $tape
+          ;;
+    -info)
+           shift
+           info
+           ;;
+    -reset)
+           shift
+           reset
+           ;;
+    -eject)
+           shift
+           eject
+           ;;
+    --help|-help)
+           echo "-slot {current|next|previous|first|last|$firstslot-$lastslot|clean}"
+           echo "      current  - show contents of current slot"
+           echo "      next     - load tape from next slot"
+           echo "      previous - load tape from previous slot"
+           echo "      first    - load tape from first slot"
+           echo "      last     - load tape from last slot"
+           echo "      $firstslot - $lastslot   - load tape from slot <slot #>"
+           echo "      clean    - Clean the drive"
+           echo "-device   : Show current tape device"
+           echo "-reset    : Reset changer to known state"
+           echo "-eject    : Eject current tape from drive"
+           echo "-info     : Output {current slot | # of slots | can changer go backwards}"
+           echo "-help     : Display this help"
+           ;;
+    *)
+       echo "<usage> $myname -{slot|device|reset|eject|help}"
+       ;;
+ esac
diff --git a/changer-src/chg-mtx.sh.in b/changer-src/chg-mtx.sh.in
new file mode 100644 (file)
index 0000000..ba9f724
--- /dev/null
@@ -0,0 +1,286 @@
+#!/bin/sh 
+#
+# Exit Status:
+# 0 Alles Ok
+# 1 Illegal Request
+# 2 Fatal Error
+#
+
+# try to hit all the possibilities here
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin
+export PATH
+
+if [ -d "@AMANDA_DBGDIR@" ]; then
+       logfile=@AMANDA_DBGDIR@/changer.debug
+else
+       logfile=/dev/null
+fi
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+myname=$0
+
+tape=`amgetconf$SUF tapedev`
+TAPE=`amgetconf$SUF changerdev`; export TAPE # for mtx command
+if [ "$tape" = "/dev/null" -o "$TAPE" = "/dev/null" ]; then
+  echo "Both tapedev and changerdev must be specified in config file";
+  exit 2;
+fi
+
+MTX=@MTX@
+
+if [ -x $sbindir/ammt$SUF ]; then
+       MT=$sbindir/ammt$SUF
+       MTF=-f
+elif [ -x "@MT@" ]; then
+       MT=@MT@
+       MTF=@MT_FILE_FLAG@
+else
+       answer="<none> $myname: mt program not found"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+echo MT "->" $MT $MTF >> $logfile
+
+if [ -x $sbindir/amdd$SUF ]; then
+       DD=$sbindir/amdd$SUF
+elif [ -x "@DD@" ]; then
+       DD=@DD@
+else
+       answer="<none> $myname: dd program not found"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+echo DD "->" $DD >> $logfile
+
+firstslot=1
+lastslot=5
+# counted from 1 !!!
+cleanslot=6
+
+changerfile=`amgetconf$SUF changerfile`
+
+cleanfile=$changerfile-clean
+accessfile=$changerfile-access
+[ ! -f $cleanfile ] && echo 0 > $cleanfile
+[ ! -f $accessfile ] && echo 0 > $accessfile
+cleancount=`cat $cleanfile`
+accesscount=`cat $accessfile`
+#
+
+readstatus() {
+  used=`$MTX -s |
+    sed -n 's/Drive: No tape Loaded/-1/p;s/Drive: tape \(.\) loaded/\1/p'`
+
+  if [ -z "$used" ]; then
+    used="-1";
+  fi
+}
+
+
+eject() {
+  readstatus 
+  if [ $used -gt 0 ];then
+    $MTX -u $used
+    answer="0 $tape"
+    code=0
+    echo "Exit -> $answer" >> $logfile
+    echo "$answer"
+    exit $code
+  else
+    answer="<none> $myname: Drive was not loaded"
+    code=1
+    echo "Exit -> $answer" >> $logfile
+    echo "$answer"
+    exit $code
+  fi
+}
+
+reset() {
+  readstatus
+  if [ $used -gt 0 ];then
+    $MTX -u $used
+  fi
+  res=`$MTX -l 1`
+  if [ $? -eq 0 ];then
+    answer="1 $tape"
+    code=0
+    echo "Exit -> $answer" >> $logfile
+    echo "$answer"
+    exit $code
+  else
+    answer="1 $res"
+    code=1
+    echo "Exit -> $answer" >> $logfile
+    echo "$answer"
+    exit $code
+  fi
+}
+#
+#
+loadslot() {
+  readstatus
+  echo "     -> loaded $used" >> $logfile
+  whichslot=$1
+  case $whichslot in
+    current)
+            if [ $used -lt 0 ];then
+              $MTX -l 1
+              used=1
+            fi
+            answer="$used $tape"
+            code=0
+            echo "Exit -> $answer" >> $logfile
+            echo "$answer"
+            exit $code
+            ;;
+    next|advance)
+         load=`expr $used + 1`
+         [ $load -gt $lastslot ] && load=$firstslot
+         ;;
+    prev)
+         load=`expr $used - 1`
+         [ $load -lt $firstslot ] && load=$lastslot
+         ;;
+    first)
+         load=$firstslot
+         ;;
+    last)
+         load=$lastslot
+         ;;
+    [$firstslot-$lastslot])
+         load=$1
+         ;;
+    clean)
+         load=$cleanslot
+         ;;
+    *)
+       answer="<none> $myname: illegal request: \"$whichslot\""
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+       ;;
+    esac
+
+    if [ $load = $used ]; then
+        answer="$used $tape"
+        code=0
+        echo "Exit -> $answer" >> $logfile
+        echo "$answer"
+        exit $code
+    fi
+
+    if [ $load = $cleanslot ]; then
+       expr $cleancount + 1 > $cleanfile
+       echo 0 > $accessfile
+    else
+       expr $accesscount + 1 > $accessfile
+       if [ $accesscount -gt 9 ]; then
+               $myname -slot clean >/dev/null
+       fi
+    fi
+
+    # Slot 6 might contain an ordinary tape rather than a cleaning
+    # tape. A cleaning tape auto-ejects; an ordinary tape does not.
+    # We therefore have to read the status again to check what
+    # actually happened.
+    readstatus
+       
+
+    if [ $used -gt 0 ];then
+      echo "     -> unload $used" >> $logfile
+      res=`$MTX -u $used`
+      status=$?
+      echo "     -> status $status" >> $logfile
+      echo "     -> res    $res" >> $logfile
+      if [ $status -ne 0 ];then
+        answer="<none> $myname: $res"
+        code=2
+        echo "Exit -> $answer" >> $logfile
+        echo "$answer"
+        exit $code
+      fi
+    fi
+    if [ $whichslot = advance ];then
+      answer="$load /dev/null"
+      code=0
+      echo "Exit -> $answer" >> $logfile
+      echo "$answer"
+      exit $code
+    fi
+    echo "     -> load   $load" >> $logfile
+    res=`$MTX -l $load`
+    status=$?
+    echo "     -> status $status" >> $logfile
+    echo "     -> res    $res" >> $logfile
+    if [ $status -eq 0 ];then
+      echo "     -> rew $load" >> $logfile
+      $MT $MTF $tape rewind
+      $DD if=$tape bs=32k count=1 >> $logfile 2>&1
+      answer="$load $tape"
+      code=0
+    else
+      answer="$load $res"
+      code=2
+    fi
+    echo "Exit -> $answer" >> $logfile
+    echo "$answer"
+    exit $code
+}
+#
+info() {
+  readstatus
+  echo "     -> info   $used" >> $logfile
+  if [ $used -lt 0 ];then
+    used=0
+  fi
+  answer="$used $lastslot 1"
+  code=0
+  echo "Exit -> $answer" >> $logfile
+  echo "$answer"
+  exit $code
+}
+#
+echo Args "->" "$@" >> $logfile
+while [ $# -ge 1 ];do
+  case $1 in
+    -slot)
+          shift
+          loadslot $*
+          ;;
+    -info)
+          shift
+          info
+          ;;
+    -reset)
+           shift
+           reset
+           ;;
+    -eject)
+           shift
+           eject
+           ;;
+    *)
+       answer="<none> $myname: Unknown option $1"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+       ;;
+  esac
+done
diff --git a/changer-src/chg-multi.sh.in b/changer-src/chg-multi.sh.in
new file mode 100644 (file)
index 0000000..0103c81
--- /dev/null
@@ -0,0 +1,464 @@
+#! /bin/sh
+#
+# 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.
+#
+# Author: James da Silva, Systems Design and Analysis Group
+#                         Computer Science Department
+#                         University of Maryland at College Park
+#
+
+#
+# chg-multi.sh - generic tape changer script
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+pname="chg-multi"
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+if [ -d "@AMANDA_DBGDIR@" ]; then
+       logfile=@AMANDA_DBGDIR@/changer.debug
+else
+       logfile=/dev/null
+fi
+
+echo Args "->" "$@" >> $logfile
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+ourconf=`amgetconf$SUF changerfile`
+
+if [ -x $sbindir/ammt$SUF ]; then
+       MT=$sbindir/ammt$SUF
+       MTF=-f
+elif [ -x "@MT@" ]; then
+       MT=@MT@
+       MTF=@MT_FILE_FLAG@
+else
+       answer="<none> $myname: mt program not found"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+echo MT "->" $MT $MTF >> $logfile
+
+EXPR=expr
+# EXPR=/usr/local/bin/expr # in case you need a more powerful expr...
+
+# read in some config parameters
+
+if [ ! -f "$ourconf" ]; then
+       answer="<none> $pname: $ourconf does not exist"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+firstslot=`awk '$1 == "firstslot" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$firstslot" ]; then
+       answer="<none> $pname: firstslot not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+lastslot=`awk '$1 == "lastslot" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$lastslot" ]; then
+       answer="<none> $pname: lastslot not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+nslots=`$EXPR $lastslot - $firstslot + 1`
+
+gravity=`awk '$1 == "gravity" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$gravity" ]; then
+       answer="<none> $pname: gravity not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+needeject=`awk '$1 == "needeject" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$needeject" ]; then
+       answer="<none> $pname: needeject not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+multieject=`awk '$1 == "multieject" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$multieject" ]; then
+       echo "Note: setting multieject to a default of zero" >> $logfile
+       multieject=0
+fi
+
+ejectdelay=`awk '$1 == "ejectdelay" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$ejectdelay" ]; then
+       echo "Note: setting ejectdelay to a default of zero" >> $logfile
+       ejectdelay=0
+fi
+
+posteject=`awk '$1 == "posteject" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$posteject" ]; then
+       echo "Note: setting posteject to a default of \"true\"" >> $logfile
+       posteject=true
+fi
+
+ourstate=`awk '$1 == "statefile" {print $2}' $ourconf 2>/dev/null`
+if [ -z "$ourstate" ]; then
+       answer="<none> $pname: statefile not specified in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+# needeject and multieject are incompatible
+if [ $needeject -eq 1 ] && [ $multieject -eq 1 ] ; then
+       answer="<none> $pname: needeject and multieject cannot be both enabled in $ourconf"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+# read in state: only curslot and curloaded at the present time
+
+curslot=`awk '$1 == "curslot" {print $2}' $ourstate 2>/dev/null`
+if [ -z "$curslot" ]; then
+       curslot=$firstslot
+fi
+
+curloaded=`awk '$1 == "curloaded" {print $2}' $ourstate 2>/dev/null`
+if [ -z "$curloaded" ]; then
+       curloaded=0
+fi
+
+
+# process the command-line
+
+# control vars to avoid code duplication: not all shells have functions!
+usage=0
+checkgravity=0
+ejectslot=0
+loadslot=0
+slotempty=0
+ejectonly=0
+
+if [ $# -ge 1 ]; then command=$1; else command="-usage"; fi
+
+case "$command" in
+
+-info) # return basic information about changer
+
+       backwards=`$EXPR 1 - $gravity`
+       answer="$curslot $nslots $backwards"
+       code=0
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+       ;;
+
+-reset) # reset changer. Actually, we only reset changer state. We
+       # trust that the operator has reloaded a stack and reset the
+       # hardware. In most cases, we do not want to actually do
+       # anything: if the operator has done something with the
+       # hardware, we have no way to know what the actual current
+       # slot is. If the hardware state has not changed, and what is
+       # really wanted is to load the first slot, use "slot first"
+       # instead 
+
+       checkgravity=0
+       loadslot=1
+       newslot=$firstslot
+       curslot=$firstslot
+       # XXX put changer-specific reset here, if applicable
+       ;;
+
+-eject) # eject tape if loaded. Note that if multieject is set, this
+        # only can make sense if the position is last and gravity 1
+
+       checkgravity=0
+       loadslot=0
+       newslot=$curslot
+       ejectslot=1
+       ejectonly=1
+       if [ $multieject -eq 1 ] && \
+           ([ $gravity -eq 0 ] || [ $curslot -ne $lastslot ]) ; then 
+               # Can't do this: if we eject, the stacker is going to
+               # load the next tape, and our state will be botched
+               answer="$curslot $pname: Cannot use -eject with multieject/nogravity/notlastslot"
+               code=1
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi    
+       if [ $curloaded -eq 0 ]; then
+               answer="$curslot $pname: slot already empty"
+               code=1
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+       ;;
+
+-slot) # change to slot
+
+       checkgravity=1
+       loadslot=1
+
+       slotparm=$2
+       case "$slotparm" in
+       [0-9]*) 
+               newslot=$slotparm
+               if [ $newslot -gt $lastslot ] || \
+                    [ $newslot -lt $firstslot ] ; then
+                       answer="$newslot $pname: no slot $newslot: legal range is $firstslot ... $lastslot"
+                       code=1
+                       echo "Exit -> $answer" >> $logfile
+                       echo "$answer"
+                       exit $code
+               fi
+               ;;
+       current)
+               newslot=$curslot
+               ;;
+       first)
+               newslot=$firstslot
+               ;;
+       last)
+               newslot=$lastslot
+               ;;
+       next|advance)
+               newslot=`$EXPR $curslot + 1`
+               if [ $newslot -gt $lastslot ]; then
+                       newslot=$firstslot
+               fi
+               if [ $slotparm = advance ]; then
+                       loadslot=0
+               fi
+               ;;
+       prev)
+               newslot=`$EXPR $curslot - 1`
+               if [ $newslot -lt $firstslot ]; then
+                       newslot=$lastslot
+               fi
+               ;;
+       *)
+               answer="<none> $pname: bad slot name \"$slotparm\""
+               code=1
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+               ;;
+       esac
+       ;;
+*)
+       usage=1
+       ;;
+esac
+
+
+if [ $usage -eq 1 ]; then
+       answer="<none> usage: $pname {-reset | -slot [<slot-number>|current|next|prev|advance] | -info | -eject}"
+       code=2
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+
+# check for legal move
+
+if [ $checkgravity -eq 1 ] && [ $gravity -ne 0 ] ; then
+       if [ $newslot -lt $curslot ] || [ "$slotparm" = "prev" ] ; then
+               answer="$newslot $pname: cannot go backwards in gravity stacker"
+               code=1
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+fi
+
+# Do the 'mt offline' style of stacker control if applicable
+if [ $multieject -eq 1 ] && [ $loadslot -eq 1 ] && [ $newslot -ne $curslot ]
+then
+       # XXX put changer-specific load command here, if applicable
+
+       curloaded=0             # unless something goes wrong
+       slotempty=0
+
+       while [ $curslot -ne $newslot ]; do
+           device=`awk '$1 == "slot" && $2 == '$curslot' {print $3}' $ourconf 2>/dev/null`
+           if [ "$device" = "" ]; then
+               answer="$curslot $pname: slot $curslot device not specified in $ourconf"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+           fi
+           echo "     -> offline $device" >> $logfile
+           $MT $MTF $device offline >> $logfile 2>&1
+           if [ $? -ne 0 ]; then
+               answer="$newslot $pname: $device: unable to change to slot $curslot"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+           fi
+           [ $ejectdelay -gt 0 ] && sleep $ejectdelay
+           echo "     -> running $posteject $device" >> $logfile
+           $posteject $device >> $logfile 2>&1
+           status=$?
+           if [ $status -ne 0 ]; then
+               answer="$newslot $pname: $posteject $device failed: $status"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+           fi
+           curslot=`$EXPR $curslot + 1`
+           if [ $curslot -gt $lastslot ] ; then
+               curslot=$firstslot
+           fi
+       done
+fi
+
+if [ $ejectonly -eq 1 ] \
+     || ([ $needeject -eq 1 ] \
+           && [ $loadslot -eq 1 ] \
+           && [ $curloaded -eq 1 ] \
+           && [ $newslot -ne $curslot ])
+then
+       # XXX put changer-specific load command here, if applicable
+
+       curloaded=0             # unless something goes wrong
+       slotempty=0
+
+       # try to unload the current device
+       device=`awk '$1 == "slot" && $2 == '$curslot' {print $3}' $ourconf 2>/dev/null`
+       if [ "$device" = "" ]; then
+               answer="$curslot $pname: slot $curslot device not specified in $ourconf"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+       echo "     -> offline $device" >> $logfile
+       $MT $MTF $device offline >> $logfile 2>&1
+       if [ $? -ne 0 ]; then
+               #
+               # XXX if the changer-specific eject command can distinguish
+               # betweeen "slot empty" and more serious errors, return 1
+               # for the first case, 2 for the second case.  Generically,
+               # we just presume an error signifies an empty slot.
+               #
+               slotempty=1
+       else
+               [ $ejectonly -eq 0 ] && [ $ejectdelay -gt 0 ] && sleep $ejectdelay
+               echo "     -> running $posteject $device" >> $logfile
+               $posteject $device >> $logfile 2>&1
+               status=$?
+               if [ $status -ne 0 ]; then
+                       answer="$newslot $pname: $posteject $device failed: $status"
+                       code=2
+                       echo "Exit -> $answer" >> $logfile
+                       echo "$answer"
+                       exit $code
+               fi
+       fi
+fi
+
+if [ $loadslot -eq 1 ]; then   # load the tape from the slot
+
+       # XXX put changer-specific load command here, if applicable
+
+       curloaded=1             # unless something goes wrong
+       slotempty=0
+       curslot=$newslot
+
+       # try to rewind the device
+       device=`awk '$1 == "slot" && $2 == '$curslot' {print $3}' $ourconf 2>/dev/null`
+       if [ "$device" = "" ]; then
+               answer="$curslot $pname: slot $curslot device not specified in $ourconf"
+               code=2
+               echo "Exit -> $answer" >> $logfile
+               echo "$answer"
+               exit $code
+       fi
+       echo "     -> rewind $device" >> $logfile
+       $MT $MTF $device rewind >> $logfile 2>&1
+       if [ $? -ne 0 ]; then
+               #
+               # XXX if the changer-specific load command can distinguish
+               # betweeen "slot empty" and more serious errors, return 1
+               # for the first case, 2 for the second case.  Generically,
+               # we just presume an error signifies an empty slot.
+               #
+               slotempty=1
+               curloaded=0
+       fi
+fi
+
+# update state
+
+echo "# multi-changer state cache: DO NOT EDIT!" >  $ourstate
+echo curslot $newslot                           >> $ourstate
+echo curloaded $curloaded                       >> $ourstate
+
+# return slot info
+
+if [ $slotempty -eq 1 ]; then
+       answer="$newslot $pname: slot is empty"
+       code=1
+       echo "Exit -> $answer" >> $logfile
+       echo "$answer"
+       exit $code
+fi
+
+if [ "$command" = -slot -a "$slotparm" = advance ]; then
+       device=/dev/null
+fi
+
+answer="$newslot $device"
+code=0
+echo "Exit -> $answer" >> $logfile
+echo "$answer"
+exit $code
diff --git a/changer-src/chg-null.sh.in b/changer-src/chg-null.sh.in
new file mode 100644 (file)
index 0000000..20ee694
--- /dev/null
@@ -0,0 +1,98 @@
+#!/bin/sh 
+#
+# Exit Status:
+# 0 Alles Ok
+# 1 Illegal Request
+# 2 Fatal Error
+#
+
+# try to hit all the possibilities here
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+debugdir=@AMANDA_DEBUGDIR@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+if [ -d "$debugdir" ]
+then
+       logfile=$debugdir/changer.debug
+else
+       logfile=/dev/null
+fi
+exec 2> $logfile
+set -x
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+myname=$0
+
+EGREP='@EGREP@'
+
+firstslot=1
+totalslots=200
+
+changerfile=`amgetconf$SUF changerfile`
+
+tapedev="null:/dev/xxx$$"
+
+cleanfile=$changerfile-clean
+accessfile=$changerfile-access
+slotfile=$changerfile-slot
+[ ! -f $cleanfile ] && echo 0 > $cleanfile
+[ ! -f $accessfile ] && echo 0 > $accessfile
+[ ! -f $slotfile ] && echo $firstslot > $slotfile
+cleancount=`cat $cleanfile`
+accesscount=`cat $accessfile`
+slot=`cat $slotfile`
+
+rc=0
+
+case x$1 in
+
+x-slot) 
+
+    #
+    # handle special slots...
+    #
+    case "$2" in
+    current)   newslot=$slot           ; load=true;;
+    next)      newslot=`expr $slot + 1`; load=true;;
+    advance)   newslot=`expr $slot + 1`; load=false;;
+    prev)      newslot=`expr $slot - 1`; load=true;;
+    first)     newslot=0               ; load=true;;
+    last)      newslot=-1              ; load=true;;
+    *)         newslot=$2              ; load=true;;
+    esac
+
+    if [ 0 -gt $newslot ]
+    then
+       newslot=`expr $totalslots - 1`
+    fi
+
+    if [ $totalslots -le  $newslot ]
+    then
+       newslot=0
+    fi
+    echo $newslot > $changerfile-slot
+    slot=$newslot
+    echo $slot $tapedev
+    ;;
+
+x-info)
+    echo $slot $totalslots 1
+    ;;
+
+x-eject)
+    echo $slot $tapedev
+    ;;
+esac
+
+exit $rc
diff --git a/changer-src/chg-rait.sh.in b/changer-src/chg-rait.sh.in
new file mode 100644 (file)
index 0000000..ceeffe7
--- /dev/null
@@ -0,0 +1,218 @@
+#!/bin/sh
+
+# chg-rait
+#
+# This assumes we have rait-striped drives in several
+# other amanda changer configs.
+#
+# so we have a changerfile that lists other changers and
+# changer files.
+#   nchangers=3
+#   tpchanger_1="chg-mtx"
+#   changerdev_1="/dev/mtx1"
+#   changerfile_1="/some/file1"
+#   tapedev_1="/some/dev"
+#   tpchanger_2="chg-mtx"
+#   changerdev_2="/dev/mtx2"
+#   changerfile_2="/some/file2"
+#   tapedev_2="/some/dev"
+#   tpchanger_3="chg-mtx"
+#   changerdev_3="/dev/mtx3"
+#   changerfile_3="/some/file3"
+#   tapedev_3="/some/dev"
+#
+# the tapedev_n entries are only needed if the changer script in question
+# uses tapedev.
+#
+
+#
+# debugging...
+#
+if [ -d "@AMANDA_DBGDIR@" ]; then
+       DBGFILE=@AMANDA_DBGDIR@/rait-changer.debug
+       KIDDEBUG=@AMANDA_DBGDIR@/changer.debug
+       WORK=@AMANDA_DBGDIR@/chgwork$$
+else
+       DBGFILE=/dev/null
+       KIDDEBUG=/dev/null
+       WORK=/tmp/chgwork$$
+fi
+
+exec 2>$DBGFILE
+echo "args: $0 $*" >&2
+set -x 
+
+#
+# the usual config fun
+#
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+        SUF="-@VERSION@";
+else
+       SUF=
+fi
+getconf=$sbindir/amgetconf$SUF
+
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH 
+
+changerfile=`$getconf changerfile`
+. $changerfile
+
+#
+# get config items that other changers use to put in our
+# fake amanda.conf files.
+#
+org=`$getconf ORG`
+mailto=`$getconf mailto`
+
+#
+# make a working directory (with amanda.conf) for each changer, and start the
+# changer script in background for each one
+#
+
+i=1
+while [ $i -le $nchangers ]
+do
+   eval tpchanger=\$tpchanger_$i
+   eval changerdev=\$changerdev_$i
+   eval changerfile=\$changerfile_$i
+   eval tapedev=\$tapedev_$i
+
+   mkdir -p $WORK/$i
+   cd $WORK/$i
+
+   cat >> amanda.conf <<EOF
+org            "$ORG"
+mailto         "$mailto"
+tpchanger      "$tpchanger"
+changerdev     "$changerdev"
+changerfile    "$changerfile"
+tapedev        "$tapedev"
+
+define tapetype EXABYTE {
+    comment "default tapetype"
+    length 4200 mbytes
+    filemark 48 kbytes
+    speed 474 kbytes                   
+}
+EOF
+
+    (
+       $tpchanger "$@"
+       echo "$?"> exitcode 
+    )  > stdout 2>stderr &
+
+   i=`expr $i + 1`
+done
+
+wait
+
+#
+# once they've all finished, collect up the results
+#
+
+myexit=0
+myslot=-1
+mymax=65536
+myflag=1
+mydev=""
+mysep="{"
+
+case x$1 in
+x-slot|x-reseti|x-eject|x-search|x-label)
+
+    #
+    # read slot number and device from each
+    # slot numbers must match(?!), and is our resulting slot number
+    # resulting device is {dev1,dev2,...} from each one
+    #
+    i=1
+    while [ $i -le $nchangers ]
+    do
+       read exitcode < $WORK/$i/exitcode
+       read n dev < $WORK/$i/stdout
+       echo -------------- >&2
+        cat $WORK/$i/stderr >&2
+       cat $KIDDEBUG >&2
+       echo -------------- >&2
+
+       if [ "$exitcode" != 0 ]
+       then
+           myexit=$exitcode
+       fi
+       if [ $myslot = -1 ]
+       then
+           myslot=$n
+       fi
+       if [ $n != $myslot ]
+       then
+            # synch error!
+           myexit=1
+           echo "stackers are out of synch, issue a reset" >&2
+       fi
+       mydev="$mydev$mysep$dev"
+       mysep=","
+
+       i=`expr $i + 1`
+    done
+    mydev="rait:$mydev}"
+    echo $myslot $mydev
+    ;;
+x-info)
+    #
+    # read info from each
+    # slot numbers must match(?!), and is our resulting slot number
+    # minimum max slots is our resulting max slots
+    # if any can't go backwards, the aggregate can't either
+    #
+    i=1
+    while [ $i -le $nchangers ]
+    do
+       read exitcode < $WORK/$i/exitcode
+       read n max flag < $WORK/$i/stdout
+       echo -------------- >&2
+        cat $WORK/$i/stderr >&2
+       cat $KIDDEBUG >&2
+       echo -------------- >&2
+
+       if [ "$exitcode" != 0 ]
+       then
+            myexit=$exitcode
+       fi
+       if [ $myslot = -1 ]
+       then
+           myslot=$n
+       fi
+       if [ $n != $myslot ]
+       then
+            # synch error!
+           myexit=1
+           echo "stackers are out of synch, issue a -reset" >&2
+       fi
+       if [ $max -lt $mymax ]
+       then
+           mymax=$max
+       fi
+       if [ $flag = 0 ]
+       then
+           myflag=0
+       fi
+       i=`expr $i + 1`
+    done
+    echo $myslot $mymax $myflag
+
+esac
+
+#
+# clean up work directories
+#
+rm -rf $WORK
+
+exit $myexit
diff --git a/changer-src/chg-rth.pl.in b/changer-src/chg-rth.pl.in
new file mode 100644 (file)
index 0000000..96c7a79
--- /dev/null
@@ -0,0 +1,301 @@
+#!@PERL@
+
+# Catch for sh/csh on systems without #! ability.
+eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
+       & eval 'exec @PERL@ -S $0 $argv:q'
+               if 0;
+
+# rth-changer - 
+#   A tape changer script for the Robotic Tape Handling system OEM'd
+#   by Andataco (RTH-406) for use with Amanda, the Advanced Maryland
+#   Network Disk Archiver.
+#
+#    Author: Erik Frederick 1/10/97
+#            edf@tyrell.mc.duke.edu
+#
+# This changer script controls the HP c1553 tape drive via a
+# Peripheral Vision Inc. SCSI control subsystem that interprets
+# commands sent on the SCSI bus.  It may work with other tape drives
+# containing the PVI board.
+#
+# Permission to freely use and distribute is granted.
+#
+
+require 5.001;
+
+use Getopt::Long;
+
+$pname = "rth-changer";
+
+$prefix="@prefix@";
+$prefix=$prefix;               # avoid warnings about possible typo
+$exec_prefix="@exec_prefix@";
+$exec_prefix=$exec_prefix;     # ditto
+$sbindir="@sbindir@";
+$libexecdir="@libexecdir@";
+if ("@USE_VERSION_SUFFIXES@" eq "yes") {
+    $suf = "-@VERSION@";
+} else {
+    $suf = "";
+}
+
+if (-x "$sbindir/ammt$SUF") {
+       $MT="$sbindir/ammt$SUF";
+       $MTF="-f";
+} elsif (-x "@MT@") {
+       $MT="@MT@";
+       $MTF="@MT_FILE_FLAG@";
+} else {
+       print "<none> $pname: mt program not found\n";
+       exit(1);
+}
+
+$tapeDevice=`$sbindir/amgetconf$SUF tapedev`;
+
+sub getCurrentTape {
+
+  if (!sysopen(RTH, $tapeDevice, 2)) {
+    print "$currentTape $pname: error in opening `$tapeDevice' for getting current tape: $!\n";
+    exit(2);
+  }
+  if (syswrite(RTH, "Rd_ElS", 6) != 6) {
+    print "$currentTape $pname: error in writing `Rd_ElS' to `$tapeDevice': $!\n";
+    exit(2);
+  }
+  if (!close(RTH)) {
+    print "$currentTape $pname: error in closing `$tapeDevice' for getting current tape: $!\n";
+    exit(2);
+  }
+
+  if (!sysopen(RTH, $tapeDevice, 2)) {
+    print "$currentTape $pname: error in opening `$tapeDevice' for getting current tape: $!\n";
+    exit(2);
+  }
+  if (sysread(RTH, $status, 136) != 136) {
+    print "$currentTape $pname: error in reading rth status.\n";
+    exit(2);
+  }
+  if (!close(RTH)) {
+    print "$currentTape $pname: error in closing `$tapeDevice' for getting current tape: $!\n";
+    exit(2);
+  }
+
+  @statusBits=unpack("c*",$status);
+
+  if( ($statusBits[18] == 0x1) || ($statusBits[18]== 0x9)) {
+    return ($statusBits[27]-1);
+  }
+
+  return (0);
+}
+
+
+sub getTapeStatus {
+
+  if (!sysopen(RTH, $tapeDevice, 2)) {
+    print "$currentTape $pname: error in opening `$tapeDevice' for getting tape status: $!\n";
+    exit(2);
+  }
+  if (syswrite(RTH, "Rd_ElS", 6) != 6) {
+    print "$currentTape $pname: error in writing `Rd_ElS' to `$tapeDevice': $!\n";
+    exit(2);
+  }
+  if (!close(RTH)) {
+    print "$currentTape $pname: error in closing `$tapeDevice' for getting tpae status: $!\n";
+    exit(2);
+  }
+
+  if (!sysopen(RTH, $tapeDevice, 2)) {
+    print "$currentTape $pname: error in opening `$tapeDevice' for getting tape status: $!\n";
+    exit(2);
+  }
+  if (sysread(RTH, $status, 136) != 136) {
+    print "$currentTape $pname: error in reading rth status for tape $currentTape.\n";
+    exit(2);
+  }
+  if (!close(RTH)) {
+    print "$currentTape $pname: error in closing `$tapeDevice' for getting tape status: $!\n";
+    exit(2);
+  }
+
+  @statusBits=unpack("c*",$status);
+
+  $curTape=0;
+  for($i=42;$i<187;$i+=16) {
+    if($statusBits[$i] == 0x9) {
+      $slots[$curTape] = 1;
+    }
+    else {
+      $slots[$curTape] = 0;
+    }
+    $curTape++;
+  }
+
+  return (@slots);
+}
+
+sub rthLoad {
+  my($tape) = @_;
+
+  $command = sprintf "GeT%d", $tape;
+  if (!sysopen(RTH, $tapeDevice, 2)) {
+    print "$currentTape $pname: error in opening `$tapeDevice' for loading tape: $!\n";
+    exit(2);
+  }
+  if (syswrite(RTH, $command, 4) != 4) {
+    print "$currentTape $pname: error in loading tape by writing `$command' to `$tapeDevice': $!\n";
+    exit(2);
+  }
+  if (!close (RTH)) {
+    print "$currentTape $pname: error in closing `$tapeDevice' when trying to load tape: $!\n";
+    exit(2);
+  }
+}
+
+sub rthUnload {
+  my($tape) = @_;
+
+  $command = sprintf "PuT%d", $tape;
+  if (!sysopen(RTH, $tapeDevice, 2)) {
+    print "$currentTape $pname: error in opening `$tapeDevice' for unloading tape: $!\n";
+    exit(2);
+  }
+  if (syswrite(RTH, $command, 4) != 4) {
+    print "$currentTape $pname: error in unloading tape by writing `$command' to `$tapeDevice': $!\n";
+    exit(2);
+  }
+  if (!close (RTH)) {
+    print "$currentTape $pname: error in closing `$tapeDevice' when trying to unload tape: $!\n";
+    exit(2);
+  }
+}
+
+sub testTape {
+  my($tape) = @_;
+
+  @slots=getTapeStatus();
+
+  if($currentTape == $tape) {
+    return;
+  }
+
+  if($slots[$tape-1] == 0) {
+    print "<none> $pname: no tape in slot requested\n";
+    exit(1);
+  }
+  if($tape>6) {
+    print $tape," $pname: requested a tape > 6\n";
+    exit(2);
+  }
+  if($tape<1) {
+    print $tape," $pname: requested a tape < 1\n";
+    exit(2);
+  }
+  return;
+}
+
+sub changeTape {
+  my($tape) = @_;
+
+  if($tape==$currentTape) {
+    return;
+  }
+
+  testTape($tape);
+
+  if($currentTape==0) {
+    rthLoad($tape);
+    $currentTape=$tape;
+    return;
+  }
+  else {
+    rthUnload($currentTape);
+    rthLoad($tape);
+    $currentTape=$tape;
+  }
+}
+    
+
+$result = &GetOptions("slot=s", "info", "reset", "eject"); 
+
+system($MT, 'rewind');
+
+$nSlots=6;
+$firstTape=1;
+$lastTape=6;
+$currentTape=getCurrentTape(); 
+
+if($opt_slot) {
+  if($opt_slot =~ /first/) {
+    changeTape(1);
+    print $currentTape, " ", $tapeDevice, "\n";
+  }
+  if($opt_slot =~ /last/) {
+    changeTape(6);
+    print $currentTape, " ", $tapeDevice, "\n";
+  }
+  if($opt_slot =~ /current/) {
+    changeTape($currentTape);
+    print $currentTape, " ", $tapeDevice, "\n";
+  }
+  if($opt_slot =~ /next/) {
+    $tape=$currentTape+1;
+    if ($tape>6) {
+      $tape=1;
+    }
+    changeTape($tape);
+    print $currentTape, " ", $tapeDevice,"\n";
+  }
+  if($opt_slot =~ /prev/) {
+    $tape=$currentTape-1;
+    if($tape<1) {
+      $tape=6;
+    }
+    changeTape($tape);
+    print $currentTape, " ", $tapeDevice,"\n";
+  }
+  if($opt_slot =~ /\d/) {
+    changeTape($opt_slot);
+    print $currentTape, " ", $tapeDevice,"\n";
+  }
+  if($opt_slot =~ /advance/) {
+    $tape=$currentTape+1;
+    if ($tape>6) {
+      $tape=1;
+    }
+    if($currentTape) { 
+      rthUnload($currentTape);
+    }
+    print $currentTape, " ", "/dev/null","\n";
+  }
+
+  exit 0;
+}
+
+if($opt_info) {
+  print $currentTape, " 6 1\n";
+
+  exit 0;
+}
+
+if($opt_reset) {
+  changeTape(1);
+  print $currentTape, " ",$tapeDevice,"\n";
+  exit 0;
+}
+
+if($opt_eject) {
+  if($currentTape) { 
+    rthUnload($currentTape);
+    print "0 ",$tapeDevice,"\n";
+    exit 0;
+  } 
+  else {
+    print "0 $pname: drive was not loaded\n";
+    exit 1;
+  }
+}
+
+print "$pname: No command was received.  Exiting.\n";
+exit 1;
diff --git a/changer-src/chg-scsi-chio.c b/changer-src/chg-scsi-chio.c
new file mode 100644 (file)
index 0000000..2ac6444
--- /dev/null
@@ -0,0 +1,902 @@
+/*
+ *  $Id: chg-scsi-chio.c,v 1.1.2.3.6.3 2003/01/26 19:20:56 martinea Exp $
+ *
+ *  chg-scsi.c -- generic SCSI changer driver
+ *
+ *  This program provides a driver to control generic
+ *  SCSI changers, no matter what platform.  The host/OS
+ *  specific portions of the interface are implemented
+ *  in libscsi.a, which contains a module for each host/OS.
+ *  The actual interface for HP/UX is in scsi-hpux.c;
+ *  chio is in scsi-chio.c, etc..  A prototype system
+ *  dependent scsi interface file is in scsi-proto.c.
+ *
+ *  Copyright 1997, 1998 Eric Schnoebelen <eric@cirr.com>
+ *
+ * This module based upon seagate-changer, by Larry Pyeatt
+ *                  <pyeatt@cs.colostate.edu>
+ *
+ * The original introductory comments follow:
+ *
+ * This program was written to control the Seagate/Conner/Archive
+ * autoloading DAT drive.  This drive normally has 4 tape capacity
+ * but can be expanded to 12 tapes with an optional tape cartridge.
+ * This program may also work on onther drives.  Try it and let me
+ * know of successes/failures.
+ *
+ * I have attempted to conform to the requirements for Amanda tape
+ * changer interface.  There could be some bugs.  
+ *
+ * This program works for me under Linux with Gerd Knorr's 
+ * <kraxel@cs.tu-berlin.de> SCSI media changer driver installed 
+ * as a kernel module.  The kernel module is available at 
+ * http://sunsite.unc.edu/pub/Linux/kernel/patches/scsi/scsi-changer*
+ * Since the Linux media changer is based on NetBSD, this program
+ * should also work for NetBSD, although I have not tried it.
+ * It may be necessary to change the IOCTL calls to work on other
+ * OS's.  
+ *
+ * (c) 1897 Larry Pyeatt,  pyeatt@cs.colostate.edu 
+ * 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.  The author makes no representations about the
+ * suitability of this software for any purpose.   It is provided "as is"
+ * without express or implied warranty.
+ *
+ * Michael C. Povel 03.06.98 added ejetct_tape and sleep for external tape
+ * devices, and changed some code to allow multiple drives to use their
+ * own slots. Also added support for reserverd slots.
+ * At the moment these parameters are hard coded and only tested under Linux
+ * 
+ */
+
+#include "config.h"
+#include "amanda.h"
+#include "conffile.h"
+#include "libscsi.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,
+    CHANGERDEV,USAGECOUNT,SCSITAPEDEV, TAPESTATFILE
+    } token_t;
+
+typedef struct {
+  char *word;
+  int 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 }
+};
+
+void init_changer_struct(changer_t *chg,int number_of_config)
+     /* Initialize datasructures with default values */
+{
+  int i;
+  
+  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;
+    }
+  }
+}
+
+void dump_changer_struct(changer_t chg)
+     /* Dump of information for debug */
+{
+  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));
+    else
+      dbprintf(("  Devicename    : none\n"));
+    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));
+    else
+      dbprintf(("  statfile      : none\n"));
+    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));
+    else
+      dbprintf(("  Cleanfile     : none\n"));
+    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 */
+{
+  int i;
+
+  if (chg->device != NULL)
+    free(chg->device);
+  for (i=0; i<chg->number_of_configs; i++){
+    if (chg->conf[i].device != NULL)
+      free(chg->conf[i].device);
+    if (chg->conf[i].slotfile != NULL)
+      free(chg->conf[i].slotfile);
+    if (chg->conf[i].cleanfile != NULL)
+      free(chg->conf[i].cleanfile);
+    if (chg->conf[i].timefile != NULL)
+      free(chg->conf[i].timefile);
+  }
+  if (chg->conf != NULL)
+    free(chg->conf);
+  chg->conf = NULL;
+  chg->device = NULL;
+}
+
+void parse_line(char *linebuffer,int *token,char **value)
+     /* This function parses a line, and returns the token an value */
+{
+  char *tok;
+  int i;
+  int ready = 0;
+  *token = -1;  /* No Token found */
+  tok=strtok(linebuffer," \t\n");
+
+  while ((tok != NULL) && (tok[0]!='#')&&(ready==0)){
+    if (*token != -1){
+      *value=tok;
+      ready=1;
+    } else {
+      i=0;
+      while ((t_table[i].word != NULL)&&(*token==-1)){
+        if (0==strcasecmp(t_table[i].word,tok)){
+          *token=t_table[i].token;
+        }
+        i++;
+      }
+    }
+    tok=strtok(NULL," \t\n");
+  }
+  return;
+}
+
+int read_config(char *configfile, changer_t *chg)
+     /* This function reads the specified configfile and fills the structure */
+{
+  int numconf;
+  FILE *file;
+  int init_flag = 0;
+  int drivenum=0;
+  char *linebuffer = NULL;
+  int token;
+  char *value;
+
+  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"))){
+    return (-1);
+  }
+
+  amfree(linebuffer);
+  while (NULL!=(linebuffer=agets(file))){
+      parse_line(linebuffer,&token,&value);
+      if (token != -1){
+        if (0==init_flag) {
+          if (token != NUMDRIVE){
+            init_changer_struct(chg,numconf);
+          } else {
+            numconf = atoi(value);
+            init_changer_struct(chg,numconf);
+          }
+          init_flag=1;
+        }
+        switch (token){
+        case NUMDRIVE: if (atoi(value) != numconf)
+          fprintf(stderr,"Error: number_drives at wrong place, should be "\
+                  "first in file\n");
+        break;
+        case EJECT:
+          chg->eject = atoi(value);
+          break;
+        case SLEEP:
+          chg->sleep = atoi(value);
+          break;
+        case CHANGERDEV:
+          chg->device = stralloc(value);
+          break;
+        case SCSITAPEDEV:
+          chg->conf[drivenum].scsitapedev = stralloc(value);
+          break;
+        case TAPESTATFILE:
+          chg->conf[drivenum].tapestatfile = stralloc(value);
+          break;
+        case CLEANMAX:
+          chg->cleanmax = atoi(value);
+          break;
+        case DRIVE:
+          drivenum = atoi(value);
+          if(drivenum >= numconf){
+            fprintf(stderr,"Error: drive must be less than number_drives\n");
+          }
+          break;
+        case DRIVENUM:
+          if (drivenum < numconf){
+            chg->conf[drivenum].drivenum = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " drivenum ignored\n");
+          }
+          break;
+        case START:
+          if (drivenum < numconf){
+            chg->conf[drivenum].start = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " startuse ignored\n");
+          }
+          break;
+        case END:
+          if (drivenum < numconf){
+            chg->conf[drivenum].end = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " enduse ignored\n");
+          }
+          break;
+        case CLEAN:
+          if (drivenum < numconf){
+            chg->conf[drivenum].cleanslot = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " cleanslot ignored\n");
+          }
+          break;
+        case DEVICE:
+          if (drivenum < numconf){
+            chg->conf[drivenum].device = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " device ignored\n");
+          }
+          break;
+        case STATFILE:
+          if (drivenum < numconf){
+            chg->conf[drivenum].slotfile = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " slotfile ignored\n");
+          }
+          break;
+        case CLEANFILE:
+          if (drivenum < numconf){
+            chg->conf[drivenum].cleanfile = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " cleanfile ignored\n");
+          }
+          break;
+        case USAGECOUNT:
+          if (drivenum < numconf){
+            chg->conf[drivenum].timefile = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " usagecount ignored\n");
+          }
+          break;
+        default:
+          fprintf(stderr,"Error: Unknown token\n");
+          break;
+        }
+      }
+    amfree(linebuffer);
+  }
+  amfree(linebuffer);
+
+  fclose(file);
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+/*  The tape drive does not have an idea of current slot so
+ *  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)
+{
+  FILE *inf;
+  int retval;
+  if ((inf=fopen(count_file,"r")) == NULL) {
+    fprintf(stderr, "%s: unable to open current slot file (%s)\n",
+            get_pname(), count_file);
+    return 0;
+  }
+  fscanf(inf,"%d",&retval);
+  fclose(inf);
+  return retval;
+}
+
+void put_current_slot(char *count_file,int slot)
+{
+  FILE *inf;
+
+  if ((inf=fopen(count_file,"w")) == NULL) {
+    fprintf(stderr, "%s: unable to open current slot file (%s)\n",
+            get_pname(), count_file);
+    exit(2);
+  }
+  fprintf(inf, "%d\n", slot);
+  fclose(inf);
+}
+
+/* ---------------------------------------------------------------------- 
+   This stuff deals with parsing the command line */
+
+typedef struct com_arg
+{
+  char *str;
+  int command_code;
+  int takesparam;
+} argument;
+
+
+typedef struct com_stru
+{
+  int command_code;
+  char *parameter;
+} command;
+
+
+/* major command line args */
+#define COMCOUNT 5
+#define COM_SLOT 0
+#define COM_INFO 1
+#define COM_RESET 2
+#define COM_EJECT 3
+#define COM_CLEAN 4
+argument argdefs[]={{"-slot",COM_SLOT,1},
+                    {"-info",COM_INFO,0},
+                    {"-reset",COM_RESET,0},
+                    {"-eject",COM_EJECT,0},
+                    {"-clean",COM_CLEAN,0}};
+
+
+/* minor command line args */
+#define SLOTCOUNT 5
+#define SLOT_CUR 0
+#define SLOT_NEXT 1
+#define SLOT_PREV 2
+#define SLOT_FIRST 3
+#define SLOT_LAST 4
+argument slotdefs[]={{"current",SLOT_CUR,0},
+                     {"next",SLOT_NEXT,0},
+                     {"prev",SLOT_PREV,0},
+                     {"first",SLOT_FIRST,0},
+                     {"last",SLOT_LAST,0}};
+
+int is_positive_number(char *tmp) /* is the string a valid positive int? */
+{
+  int i=0;
+  if ((tmp==NULL)||(tmp[0]==0))
+    return 0;
+  while ((tmp[i]>='0')&&(tmp[i]<='9')&&(tmp[i]!=0))
+    i++;
+  if (tmp[i]==0)
+    return 1;
+  else
+    return 0;
+}
+
+void usage(char *argv[])
+{
+  int cnt;
+  printf("%s: Usage error.\n", argv[0]);
+  for (cnt=0; cnt < COMCOUNT; cnt++){
+    printf("      %s    %s",argv[0],argdefs[cnt].str);
+    if (argdefs[cnt].takesparam)
+      printf(" <param>\n");
+    else
+      printf("\n");
+  }
+  exit(2);
+}
+
+
+void parse_args(int argc, char *argv[],command *rval)
+{
+  int i=0;
+  if ((argc<2)||(argc>3))
+    usage(argv);
+  while ((i<COMCOUNT)&&(strcmp(argdefs[i].str,argv[1])))
+    i++;
+  if (i==COMCOUNT)
+    usage(argv);
+  rval->command_code = argdefs[i].command_code;
+  if (argdefs[i].takesparam) {
+    if (argc<3)
+      usage(argv);
+    rval->parameter=argv[2];      
+  }
+  else {
+    if (argc>2)
+      usage(argv);
+    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 current_slot,i;
+  if (changer_file != NULL)
+    {
+      current_slot=get_current_slot(changer_file);
+    } else {
+      current_slot =   GetCurrentSlot(fd, 0);
+    }
+  if (current_slot > maxslot){
+    current_slot = slot_offset;
+  }
+  if (current_slot < slot_offset){
+    current_slot = slot_offset;
+  }
+
+  i=0;
+  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);
+  };
+}
+
+int ask_clean(char *tapedev)
+     /* This function should ask the drive if it wants to be cleaned */
+{
+  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 */
+{
+  int counter=-1;
+  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,
+                           " -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;
+      }
+      fprintf(mailf,"\nThe usage count of your cleaning tape in slot %d",
+              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);
+
+      return;
+    }
+    put_current_slot(cnt_file,counter);
+  }
+  load(fd,drivenum,cleancart);
+  
+  if (drive_loaded(fd, drivenum))
+    unload(fd,drivenum,cleancart);  
+  unlink(usagetime);
+}
+/* ----------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+  int loaded,target,oldtarget;
+  command com;   /* a little DOS joke */
+  changer_t chg;
+  
+  /*
+   * 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.. )
+   */
+  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 */
+  int clean_slot = -1;
+  int maxclean = 0;
+  char *clean_file=NULL;
+  char *time_file=NULL;
+
+  int use_slots;
+  int slot_offset;
+  int confnum;
+
+  int fd, rc, slotcnt, drivecnt;
+  int endstatus = 0;
+  char *changer_dev, *tape_device;
+  char *changer_file = NULL;
+  char *scsitapedevice = NULL;
+
+  set_pname("chg-scsi");
+  dbopen();
+  parse_args(argc,argv,&com);
+
+  if(read_conffile(CONFFILE_NAME)) {
+    fprintf(stderr, "%s: could not find config file \"%s\"",
+                   changer_dev, conffile);
+    exit(1);
+  }
+
+  changer_dev = getconf_str(CNF_CHNGRDEV);
+  changer_file = getconf_str(CNF_CHNGRFILE);
+  tape_device = getconf_str(CNF_TAPEDEV);
+
+  /* Get the configuration parameters */
+  if (strlen(tape_device)==1){
+    read_config(changer_file,&chg);
+    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);
+    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);
+    /* get info about the changer */
+    if (-1 == (fd = OpenDevice(changer_dev, "changer_dev"))) {
+      int localerr = errno;
+      fprintf(stderr, "%s: open: %s: %s\n", get_pname(), 
+              changer_dev, strerror(localerr));
+      printf("%s open: %s: %s\n", "<none>", changer_dev, strerror(localerr));
+      dbprintf(("%s: open: %s: %s\n", get_pname(),
+                changer_dev, strerror(localerr)));
+      return 2;
+    }
+
+    if (tape_device == NULL)
+      {
+        tape_device = stralloc(changer_dev);
+      }
+
+    if (scsitapedevice == NULL)
+      {
+         scsitapedevice = stralloc(tape_device);
+      }
+
+    if ((chg.conf[confnum].end == -1) || (chg.conf[confnum].start == -1)){
+      slotcnt = get_slot_count(fd);
+      use_slots    = slotcnt;
+      slot_offset  = 0;
+    }
+    free_changer_struct(&chg);
+  } else {
+    /* get info about the changer */
+    if (-1 == (fd = OpenDevice(changer_dev))) {
+      int localerr = errno;
+      fprintf(stderr, "%s: open: %s: %s\n", get_pname(), 
+              changer_dev, strerror(localerr));
+      printf("%s open: %s: %s\n", "<none>", changer_dev, strerror(localerr));
+      dbprintf(("%s: open: %s: %s\n", get_pname(),
+                changer_dev, strerror(localerr)));
+      return 2;
+    }
+    slotcnt = get_slot_count(fd);
+    use_slots    = slotcnt;
+    slot_offset  = 0;
+    drive_num    = 0;
+    need_eject   = 0;
+    need_sleep   = 0;
+  }
+
+  drivecnt = get_drive_count(fd);
+
+  if (drive_num > drivecnt) {
+    printf("%s drive number error (%d > %d)\n", "<none>", 
+           drive_num, drivecnt);
+    fprintf(stderr, "%s: requested drive number (%d) greater than "
+            "number of supported drives (%d)\n", get_pname(), 
+            drive_num, drivecnt);
+    dbprintf(("%s: requested drive number (%d) greater than "
+              "number of supported drives (%d)\n", get_pname(), 
+              drive_num, drivecnt));
+    CloseDevice("", fd);
+    return 2;
+  }
+
+  loaded = drive_loaded(fd, drive_num);
+
+  switch(com.command_code) {
+  case COM_SLOT:  /* slot changing command */
+    if (is_positive_number(com.parameter)) {
+      if ((target = atoi(com.parameter))>=use_slots) {
+        printf("<none> no slot `%d'\n",target);
+        close(fd);
+        endstatus = 2;
+        break;
+      } else {
+        target = target+slot_offset;
+      }
+    } else
+      target=get_relative_target(fd, use_slots,
+                                 com.parameter,
+                                 loaded, 
+                                 changer_file,slot_offset,slot_offset+use_slots);
+    if (loaded) {
+      if (changer_file != NULL)
+        {
+          oldtarget=get_current_slot(changer_file);
+        } else {
+          oldtarget = GetCurrentSlot(fd, drive_num);
+        }
+      if ((oldtarget)!=target) {
+        if (need_eject)
+          eject_tape(scsitapedevice, need_eject);
+        (void)unload(fd, drive_num, oldtarget);
+        if (ask_clean(scsitapedevice))
+          clean_tape(fd,tape_device,clean_file,drive_num,
+                     clean_slot,maxclean,time_file);
+        loaded=0;
+      }
+    }
+    if (changer_file != NULL)
+      {
+      put_current_slot(changer_file, target);
+    }
+    if (!loaded && isempty(fd, target)) {
+      printf("%d slot %d is empty\n",target-slot_offset,
+             target-slot_offset);
+      close(fd);
+      endstatus = 1;
+      break;
+    }
+    if (!loaded)
+      if (load(fd, drive_num, target) != 0) {
+        printf("%d slot %d move failed\n",target-slot_offset,
+               target-slot_offset);  
+        close(fd);
+        endstatus = 2;
+        break;
+      }
+    if (need_sleep)
+      Tape_Ready(scsitapedevice, need_sleep);
+    printf("%d %s\n", target-slot_offset, tape_device);
+    break;
+
+  case COM_INFO:
+    if (changer_file != NULL)
+      {
+        printf("%d ", get_current_slot(changer_file)-slot_offset);
+      } else {
+        printf("%d ", GetCurrentSlot(fd, drive_num)-slot_offset);
+      }
+    printf("%d 1\n", use_slots);
+    break;
+
+  case COM_RESET:
+    if (changer_file != NULL)
+      {
+        target=get_current_slot(changer_file);
+      } else {
+        target = GetCurrentSlot(fd, drive_num);
+      }
+    if (loaded) {
+      if (!isempty(fd, target))
+        target=find_empty(fd,0 ,0);
+      if (need_eject)
+        eject_tape(scsitapedevice, need_eject);
+      (void)unload(fd, drive_num, target);
+      if (ask_clean(scsitapedevice))
+        clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
+                   maxclean,time_file);
+    }
+
+    if (isempty(fd, slot_offset)) {
+      printf("0 slot 0 is empty\n");
+      close(fd);
+      endstatus = 1;
+      break;
+    }
+
+    if (load(fd, drive_num, slot_offset) != 0) {
+      printf("%d slot %d move failed\n",slot_offset,
+             slot_offset);  
+      close(fd);
+      endstatus = 2;
+      break;
+    }
+    if (changer_file != NULL)
+    {
+      put_current_slot(changer_file, slot_offset);
+    }
+    if (need_sleep)
+      Tape_Ready(scsitapedevice, need_sleep);
+    if (changer_file != NULL)
+      {
+        printf("%d %s\n", get_current_slot(changer_file), tape_device);
+      } else {
+        printf("%d %s\n", GetCurrentSlot(fd, drive_num), tape_device);
+      }
+    break;
+
+  case COM_EJECT:
+    if (loaded) {
+      if (changer_file != NULL)
+        {
+          target=get_current_slot(changer_file);
+        } else {
+          target = GetCurrentSlot(fd, drive_num);
+        }
+      if (need_eject)
+        eject_tape(scsitapedevice, need_eject);
+      (void)unload(fd, drive_num, target);
+      if (ask_clean(scsitapedevice))
+        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");
+      endstatus = 1;
+    }
+    break;
+  case COM_CLEAN:
+    if (loaded) {
+      if (changer_file  != NULL)
+        {
+          target=get_current_slot(changer_file);
+        } else {
+          target = GetCurrentSlot(fd, drive_num);
+        }
+      if (need_eject)
+        eject_tape(scsitapedevice, need_eject);
+      (void)unload(fd, drive_num, target);
+    } 
+    clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
+               maxclean,time_file);
+    printf("%s cleaned\n", tape_device);
+    break;
+  };
+
+  CloseDevice("", 0);
+  dbclose();
+  return endstatus;
+}
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * tab-width: 4
+ * End:
+ */
diff --git a/changer-src/chg-scsi.c b/changer-src/chg-scsi.c
new file mode 100644 (file)
index 0000000..43bf315
--- /dev/null
@@ -0,0 +1,1784 @@
+#ifndef lint
+static char rcsid[] = "$Id: chg-scsi.c,v 1.6.2.22.2.7.2.9 2003/07/05 16:59:01 ant Exp $";
+#endif
+/*
+ * 
+ *
+ *  chg-scsi.c -- generic SCSI changer driver
+ *
+ *  This program provides the framework to control
+ *  SCSI changers. It is based on the original chg-scsi
+ *  from Eric Schnoebelen <eric@cirr.com> (Original copyright below)
+ *  The device dependent part is handled by scsi-changer-driver.c
+ *  The SCSI OS interface is handled by scsi-ostype.c
+ *
+ *  Original copyrigths:
+ *
+ *  This program provides a driver to control generic
+ *  SCSI changers, no matter what platform.  The host/OS
+ *  specific portions of the interface are implemented
+ *  in libscsi.a, which contains a module for each host/OS.
+ *  The actual interface for HP/UX is in scsi-hpux.c;
+ *  chio is in scsi-chio.c, etc..  A prototype system
+ *  dependent scsi interface file is in scsi-proto.c.
+ *
+ *  Copyright 1997, 1998 Eric Schnoebelen <eric@cirr.com>
+ *
+ * This module based upon seagate-changer, by Larry Pyeatt
+ *                  <pyeatt@cs.colostate.edu>
+ *
+ * The original introductory comments follow:
+ *
+ * This program was written to control the Seagate/Conner/Archive
+ * autoloading DAT drive.  This drive normally has 4 tape capacity
+ * but can be expanded to 12 tapes with an optional tape cartridge.
+ * This program may also work on onther drives.  Try it and let me
+ * know of successes/failures.
+ *
+ * I have attempted to conform to the requirements for Amanda tape
+ * changer interface.  There could be some bugs.  
+ *
+ * This program works for me under Linux with Gerd Knorr's 
+ * <kraxel@cs.tu-berlin.de> SCSI media changer driver installed 
+ * as a kernel module.  The kernel module is available at 
+ * http://sunsite.unc.edu/pub/Linux/kernel/patches/scsi/scsi-changer*
+ * Since the Linux media changer is based on NetBSD, this program
+ * should also work for NetBSD, although I have not tried it.
+ * It may be necessary to change the IOCTL calls to work on other
+ * OS's.  
+ *
+ * (c) 1897 Larry Pyeatt,  pyeatt@cs.colostate.edu 
+ * 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.  The author makes no representations about the
+ * suitability of this software for any purpose.   It is provided "as is"
+ * without express or implied warranty.
+ *
+ * Michael C. Povel 03.06.98 added ejetct_tape and sleep for external tape
+ * devices, and changed some code to allow multiple drives to use their
+ * own slots. Also added support for reserverd slots.
+ * At the moment these parameters are hard coded and only tested under Linux
+ * 
+ */
+
+
+#include "config.h"
+
+
+#include "amanda.h"
+
+#ifdef HAVE_DMALLOC_H
+#include <dmalloc.h>
+#endif
+
+
+#include "conffile.h"
+#include "libscsi.h"
+#include "scsi-defs.h"
+#include "tapeio.h"
+
+char *tapestatfile = NULL;
+FILE *debug_file = NULL;
+
+/* 
+ * So we have 3 devices, here will all the infos be stored after an
+ * successfull open 
+ */
+
+OpenFiles_T *pDev = NULL;
+
+/* Defined in scsi-changer-driver.c
+ */
+extern int ElementStatusValid;
+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;
+
+int do_inventory = 0;     /* Set if load/unload functions thinks an inventory should be done */
+int clean_slot = -1;
+
+typedef enum{
+  NUMDRIVE,EJECT,SLEEP,CLEANMAX,DRIVE,START,END,CLEAN,DEVICE,STATFILE,CLEANFILE,DRIVENUM,
+    CHANGERDEV,USAGECOUNT,SCSITAPEDEV, TAPESTATFILE, LABELFILE, CHANGERIDENT,
+    TAPEIDENT, EMUBARCODE, HAVEBARCODE, DEBUGLEVEL, AUTOINV
+    } token_t;
+
+typedef struct {
+  char *word;
+  int 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 }
+};
+
+void init_changer_struct(changer_t *chg,int number_of_config)
+     /* Initialize datasructures with default values */
+{
+  int i;
+  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");
+  }
+}
+
+void dump_changer_struct(changer_t chg)
+     /* Dump of information for debug */
+{
+  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(("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].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));
+    else
+      dbprintf(("  SCSITapedev   : none\n"));
+
+    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));
+    else
+      dbprintf(("  statfile      : none\n"));
+
+    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));
+    else
+      dbprintf(("  Cleanfile     : none\n"));
+
+    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 */
+{
+  int i;
+
+  if (chg->device != NULL)
+    free(chg->device);
+  for (i=0; i<chg->number_of_configs; i++){
+    if (chg->conf[i].device != NULL)
+      free(chg->conf[i].device);
+    if (chg->conf[i].slotfile != NULL)
+      free(chg->conf[i].slotfile);
+    if (chg->conf[i].cleanfile != NULL)
+      free(chg->conf[i].cleanfile);
+    if (chg->conf[i].timefile != NULL)
+      free(chg->conf[i].timefile);
+  }
+  if (chg->conf != NULL)
+    free(chg->conf);
+  chg->conf = NULL;
+  chg->device = NULL;
+}
+
+void parse_line(char *linebuffer,int *token,char **value)
+     /* This function parses a line, and returns a token and value */
+{
+  char *tok;
+  int i;
+  int ready = 0;
+  *token = -1;  /* No Token found */
+  tok=strtok(linebuffer," \t\n");
+
+  while ((tok != NULL) && (tok[0]!='#')&&(ready==0)){
+    if (*token != -1){
+      *value=tok;
+      ready=1;
+    } else {
+      i=0;
+      while ((t_table[i].word != NULL)&&(*token==-1)){
+        if (0==strcasecmp(t_table[i].word,tok)){
+          *token=t_table[i].token;
+        }
+        i++;
+      }
+    }
+    tok=strtok(NULL," \t\n");
+  }
+  return;
+}
+
+int read_config(char *configfile, changer_t *chg)
+     /* This function reads the specified configfile and fills the structure */
+{
+  int numconf;
+  FILE *file;
+  int init_flag = 0;
+  int drivenum=0;
+  char *linebuffer = NULL;
+  int token;
+  char *value;
+  char *p;
+
+  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"))){
+    return (-1);
+  }
+
+  amfree(linebuffer);
+  while ((NULL!=(linebuffer=agets(file)))) {
+      parse_line(linebuffer,&token,&value);
+      if (token != -1){
+        if (0==init_flag) {
+          if (token != NUMDRIVE){
+            init_changer_struct(chg,numconf);
+          } else {
+            numconf = atoi(value);
+            init_changer_struct(chg,numconf);
+          }
+          init_flag=1;
+        }
+        switch (token){
+        case NUMDRIVE: if (atoi(value) != numconf)
+          fprintf(stderr,"Error: number_drives at wrong place, should be "\
+                  "first in file\n");
+        break;
+        case AUTOINV:
+          chg->autoinv = 1;
+          break;
+        case EMUBARCODE:
+          chg->emubarcode = 1;
+          break;
+        case DEBUGLEVEL:
+          chg->debuglevel = stralloc(value);
+          break;
+        case EJECT:
+          chg->eject = atoi(value);
+          break;
+        case HAVEBARCODE:
+          chg->havebarcode = atoi(value);
+          break;
+       case SLEEP:
+          chg->sleep = atoi(value);
+          break;
+        case LABELFILE:
+          chg->labelfile = stralloc(value);
+          break;
+        case CHANGERDEV:
+          chg->device = stralloc(value);
+          break;
+        case SCSITAPEDEV:
+          chg->conf[drivenum].scsitapedev = stralloc(value);
+          break;
+        case TAPESTATFILE:
+          chg->conf[drivenum].tapestatfile = stralloc(value);
+          break;
+        case CHANGERIDENT:
+          chg->conf[drivenum].changerident = stralloc(value);
+          p = chg->conf[drivenum].changerident;
+          while (*p != '\0')
+          {
+            if (*p == '_')
+            {
+              *p=' ';
+            }
+            p++;
+          }
+          break;
+        case TAPEIDENT:
+          chg->conf[drivenum].tapeident = stralloc(value);
+          break;
+        case CLEANMAX:
+          chg->cleanmax = atoi(value);
+          break;
+        case DRIVE:
+          drivenum = atoi(value);
+          if(drivenum >= numconf){
+            fprintf(stderr,"Error: drive must be less than number_drives\n");
+          }
+          break;
+        case DRIVENUM:
+          if (drivenum < numconf){
+            chg->conf[drivenum].drivenum = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " drivenum ignored\n");
+          }
+          break;
+        case START:
+          if (drivenum < numconf){
+            chg->conf[drivenum].start = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " startuse ignored\n");
+          }
+          break;
+        case END:
+          if (drivenum < numconf){
+            chg->conf[drivenum].end = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " enduse ignored\n");
+          }
+          break;
+        case CLEAN:
+          if (drivenum < numconf){
+            chg->conf[drivenum].cleanslot = atoi(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " cleanslot ignored\n");
+          }
+          break;
+        case DEVICE:
+          if (drivenum < numconf){
+            chg->conf[drivenum].device = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " device ignored\n");
+          }
+          break;
+        case STATFILE:
+          if (drivenum < numconf){
+            chg->conf[drivenum].slotfile = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " slotfile ignored\n");
+          }
+          break;
+        case CLEANFILE:
+          if (drivenum < numconf){
+            chg->conf[drivenum].cleanfile = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " cleanfile ignored\n");
+          }
+          break;
+        case USAGECOUNT:
+          if (drivenum < numconf){
+            chg->conf[drivenum].timefile = stralloc(value);
+          } else {
+            fprintf(stderr,"Error: drive is not less than number_drives"\
+                    " usagecount ignored\n");
+          }
+          break;
+        default:
+          fprintf(stderr,"Error: Unknown token\n");
+          break;
+        }
+      }
+    amfree(linebuffer);
+  }
+  amfree(linebuffer);
+
+  fclose(file);
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+/*  The tape drive does not have an idea of current slot so
+ *  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)
+{
+  FILE *inf;
+  int retval;
+  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);
+  
+  /*
+   * check if we got an result
+   * if no set retval to -1 
+  */
+  if (ret == 0 || ret == EOF)
+    {
+      retval = -1;
+    }
+
+  return retval;
+}
+
+void put_current_slot(char *count_file,int slot)
+{
+  FILE *inf;
+
+  if ((inf=fopen(count_file,"w")) == NULL) {
+    fprintf(stderr, "%s: unable to open current slot file (%s)\n",
+            get_pname(), count_file);
+    exit(2);
+  }
+  fprintf(inf, "%d\n", slot);
+  fclose(inf);
+}
+
+/* 
+ * Here we handle the inventory DB
+ * With this it should be possible to do an mapping
+ * Barcode      -> Volume label
+ * Volume Label -> Barcode
+ * Volume label -> Slot number
+ * Return Values:
+ * 1 -> Action was ok
+ * 0 -> Action failed
+ *
+ * The passed struct MBC_T will hold the found entry in the DB
+ */
+
+int MapBarCode(char *labelfile, MBC_T *result)
+{
+  FILE *fp;
+  int version;
+  LabelV2_T *plabelv2;
+  int unusedpos = 0;
+  int unusedrec = 0;
+  int pos     = 0;
+  int record  = 0;
+  int volseen = 0;
+  int loop    = 1;
+  int rsize   = 0;
+
+  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",
+             labelfile,
+             result->data.voltag,
+             result->data.barcode,
+             result->action,
+             result->data.slot,
+             result->data.from);
+  
+  if (labelfile == NULL)
+    {
+      DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"Got empty labelfile (NULL)\n");
+      ChgExit("MapBarCode", "MapBarCode name of labelfile is not set\n",FATAL);
+    }
+  if (access(labelfile, F_OK) == -1)
+    {
+      DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "MapBarCode : creating %s", labelfile);
+      if ((fp = fopen(labelfile, "w+")) == NULL)
+        {
+          DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE," failed\n");
+          ChgExit("MapBarCode", "MapBarCode, creating labelfile failed\n", FATAL);
+        }
+      fprintf(fp,":%d:", LABEL_DB_VERSION);
+      fclose(fp);
+    }
+  
+  if ((fp = fopen(labelfile, "r+")) == NULL)
+    {
+       DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : failed to open %s\n", labelfile);
+       ChgExit("MapBarCode", "MapBarCode, opening labelfile for read/write failed\n", FATAL);
+    }
+  
+  fscanf(fp,":%d:", &version);
+  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);
+    }
+
+  if (( plabelv2 = (LabelV2_T *)malloc(sizeof(LabelV2_T))) == NULL)
+    {
+      DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE,"MapBarCode : malloc failed\n");
+      ChgExit("MapBarCode", "MapBarCode malloc failed\n", FATAL);
+    }
+  
+  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))
+      {
+      record++;
+      DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : (%d) VolTag \"%s\", BarCode %s, inuse %d, slot %d, from %d, loadcount %d\n",record,
+                 plabelv2->voltag,
+                 plabelv2->barcode,
+                 plabelv2->valid,
+                 plabelv2->slot,
+                 plabelv2->from,
+                 plabelv2->LoadCount);
+      switch (result->action)
+        {
+          /*
+           * Only dump the info
+           */ 
+        case BARCODE_DUMP:
+          printf("Slot -> %d, from -> %d, valid -> %d, Tag -> %s, Barcode -> %s, Loadcount %d\n",
+                 plabelv2->slot,
+                 plabelv2->from,
+                 plabelv2->valid,
+                 plabelv2->voltag,
+                 plabelv2->barcode,
+                 plabelv2->LoadCount
+                 );
+          break;
+          /*
+           * 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);
+          break;
+          /*
+           * Add an entry
+           */
+        case BARCODE_PUT:
+          /*
+           * If it is an invalid record we can use it,
+           * so save the record number.
+           * This value is used at the end if no other
+           * record/action matches.
+           */
+          if (plabelv2->valid == 0)
+            {
+                 unusedpos = pos;
+                 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);
+              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);
+              fclose(fp);
+              return(1);
+            }
+          break;
+          /*
+           * Look for an entry an return the entry
+           * if the voltag (the tape name) matches
+           */
+        case FIND_SLOT:
+          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));
+              return(1);
+           }
+          break;
+          /*
+           * Update the entry,
+           * reason can be an load, incr the LoadCount
+           * or an new tape
+           */
+        case UPDATE_SLOT:
+          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);
+              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);
+              fclose(fp);
+              return(1);
+            }
+          break;
+          /*
+           * Look for the barcode label of an given volume label
+           * return the slot number and the barcode label.
+           * If the entry is not valid return -1 as slot number
+           */
+        case BARCODE_VOL:
+         /*
+          * DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode: (%d) inside BARCODE_VOL\n", record);
+         DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"file value: %s, searched for value: %s\n", plabelv2->voltag, result->data.voltag);
+         */
+          if (strcmp(plabelv2->voltag, result->data.voltag) == 0)
+            {
+              DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : VOL %s match\n", result->data.voltag);
+              fclose(fp);
+              
+              memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
+              return(1);
+            }
+          break;
+          /*
+           * Look for an entry which matches the passed
+           * barcode label
+           */
+        case BARCODE_BARCODE:
+          if (strcmp(plabelv2->barcode, result->data.barcode) == 0)
+            {
+              DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : BARCODE %s match\n", result->data.barcode);
+              fclose(fp);
+              
+              memcpy(&(result->data), plabelv2, sizeof(LabelV2_T));
+              return(1);
+            }
+          break;
+
+        default:
+          DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : unknown action\n");
+          break;
+        }
+      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);
+       loop=0;
+      }
+    }
+
+  /*
+   * OK, if we come here and the action is either
+   * PUT or update it seems that we have to create a new
+   * record, becuae none of the exsisting records matches
+   */
+  if (result->action == BARCODE_PUT || result->action == UPDATE_SLOT )
+    {
+      /*
+       * If we have an entry where the valid flag was set to 0
+       * we can use this record, so seek to this position
+       * If we have no record for reuse the new record will be written to the end.
+       */
+      if (unusedpos != 0)
+        {
+          DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE,"MapBarCode : reuse record %d\n", unusedrec);
+          fseek(fp, unusedpos, SEEK_SET);
+        }
+      /*
+       * Set all values to zero
+       */
+      memset(plabelv2, 0, sizeof(LabelV2_T));     
+
+      strcpy(plabelv2->voltag, result->data.voltag);
+      strncpy(plabelv2->barcode, result->data.barcode, TAG_SIZE);
+      plabelv2->valid = 1;
+      plabelv2->from = result->data.from;
+      plabelv2->slot = result->data.slot;
+      fwrite(plabelv2, 1, sizeof(LabelV2_T), fp);
+      fclose(fp);
+      return(1);
+    }                                                                           
+
+  /*
+   * If we hit this point nothing was 
+   * found, so return an 0
+   */
+  fclose(fp);
+  return(0);
+}
+
+/* ---------------------------------------------------------------------- 
+   This stuff deals with parsing the command line */
+
+typedef struct com_arg
+{
+  char *str;
+  int command_code;
+  int takesparam;
+} argument;
+
+
+typedef struct com_stru
+{
+  int command_code;
+  char *parameter;
+} command;
+
+
+/* major command line args */
+#define COMCOUNT 13
+#define COM_SLOT 0
+#define COM_INFO 1
+#define COM_RESET 2
+#define COM_EJECT 3
+#define COM_CLEAN 4
+#define COM_LABEL 5
+#define COM_SEARCH 6
+#define COM_STATUS 7
+#define COM_TRACE 8
+#define COM_INVENTORY 9
+#define COM_DUMPDB 10
+#define COM_SCAN 11
+#define COM_GEN_CONF 12
+argument argdefs[]={{"-slot",COM_SLOT,1},
+                    {"-info",COM_INFO,0},
+                    {"-reset",COM_RESET,0},
+                    {"-eject",COM_EJECT,0},
+                    {"-clean",COM_CLEAN,0},
+                    {"-label",COM_LABEL,1},
+                    {"-search",COM_SEARCH,1},
+                    {"-status",COM_STATUS,1},
+                    {"-trace",COM_TRACE,1},
+                    {"-inventory", COM_INVENTORY,0},
+                    {"-dumpdb", COM_DUMPDB,0},
+                    {"-scan", COM_SCAN,0},
+                    {"-genconf", COM_GEN_CONF,0}
+       };
+
+
+/* minor command line args */
+#define SLOT_CUR 0
+#define SLOT_NEXT 1
+#define SLOT_PREV 2
+#define SLOT_FIRST 3
+#define SLOT_LAST 4
+#define SLOT_ADVANCE 5
+argument slotdefs[]={{"current",SLOT_CUR,0},
+                     {"next",SLOT_NEXT,0},
+                     {"prev",SLOT_PREV,0},
+                     {"first",SLOT_FIRST,0},
+                     {"last",SLOT_LAST,0},
+                     {"advance",SLOT_ADVANCE,0},
+       };
+#define SLOTCOUNT (sizeof(slotdefs) / sizeof(slotdefs[0]))
+
+int is_positive_number(char *tmp) /* is the string a valid positive int? */
+{
+  int i=0;
+  if ((tmp==NULL)||(tmp[0]==0))
+    return 0;
+  while ((tmp[i]>='0')&&(tmp[i]<='9')&&(tmp[i]!=0))
+    i++;
+  if (tmp[i]==0)
+    return 1;
+  else
+    return 0;
+}
+
+void usage(char *argv[])
+{
+  int cnt;
+  printf("%s: Usage error.\n", argv[0]);
+  for (cnt=0; cnt < COMCOUNT; cnt++){
+    printf("      %s    %s",argv[0],argdefs[cnt].str);
+    if (argdefs[cnt].takesparam)
+      printf(" <param>\n");
+    else
+      printf("\n");
+  }
+  exit(2);
+}
+
+
+void parse_args(int argc, char *argv[],command *rval)
+{
+  int i=0;
+  for (i=0; i < argc; i++)
+    dbprintf(("ARG [%d] : %s\n", i, argv[i]));
+  i = 0;
+  if ((argc<2)||(argc>3))
+    usage(argv);
+  while ((i<COMCOUNT)&&(strcmp(argdefs[i].str,argv[1])))
+    i++;
+  if (i==COMCOUNT)
+    usage(argv);
+  rval->command_code = argdefs[i].command_code;
+  if (argdefs[i].takesparam) {
+    if (argc<3)
+      usage(argv);
+    rval->parameter=argv[2];      
+  }
+  else {
+    if (argc>2)
+      usage(argv);
+    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 param_index,
+                       int loaded,char *slot_file,
+                       int slot_offset,int maxslot)
+{
+  int current_slot;
+  
+  current_slot = get_current_slot(slot_file);
+
+  if (current_slot > maxslot){
+    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;
+  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);
+    break;
+  };
+  return(-1); /* never executed */
+}
+
+int ask_clean(char *tapedev)
+     /* This function should ask the drive if it wants to be cleaned */
+{
+  int ret;
+
+  ret = get_clean_state(tapedev);
+
+  if (ret < 0) /* < 0 means query does not work ... */
+  {
+    return(0);
+  }
+  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 */
+{
+  int counter=-1;
+  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,
+                           " -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;
+      }
+      fprintf(mailf,"\nThe usage count of your cleaning tape in slot %d",
+              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);
+
+      return;
+    }
+    put_current_slot(cnt_file,counter);
+  }
+  load(fd,drivenum,cleancart);
+  /*
+   * Hack, sleep for some time
+   */
+
+  sleep(60);
+
+  if (drive_loaded(fd, drivenum))
+    unload(fd,drivenum,cleancart);  
+  unlink(usagetime);
+}
+/* ----------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+  int loaded,target,oldtarget;
+  command com;   /* a little DOS joke */
+  int x;
+
+  MBC_T *pbarcoderes = malloc(sizeof(MBC_T));
+  /*
+   * 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 */
+
+  int maxclean = 0;
+  char *clean_file=NULL;
+  char *time_file=NULL;
+
+  char *ptr;         /* a public pointer .... */
+  /*
+   * For the emubarcode stuff
+   */
+  int use_slots;
+  int slot_offset;
+  int confnum;
+
+  int fd, slotcnt, 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
+                                         * slot is loaded
+                                         */
+  char *scsitapedevice = NULL;
+
+  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;
+  chg.debuglevel = NULL;
+#ifdef CHG_SCSI_STANDALONE
+  printf("Ups standalone\n");
+#else
+  set_pname("chg-scsi");
+  dbopen();
+
+  dbprintf(("chg-scsi: %s\n",rcsid));
+  ChangerDriverVersion();
+
+  if (debug_file == NULL)
+    {
+        debug_file = dbfp();
+    }
+  
+  parse_args(argc,argv,&com);
+
+  pDev = (OpenFiles_T *)malloc(sizeof(OpenFiles_T) * CHG_MAXDEV);
+  memset(pDev, 0, sizeof(OpenFiles_T) * CHG_MAXDEV );
+
+
+  if ((ptr=getenv("CHG_DEBUG")) != NULL)
+    {
+      chg.debuglevel = strdup(ptr);
+    }
+
+  switch(com.command_code) 
+    {
+    case COM_SCAN:
+      ScanBus(1);
+      return(0);
+      break;
+    case COM_GEN_CONF:
+      ScanBus(0);
+      PrintConf();
+      return(0);
+      break;
+    default:
+      break;
+    }
+
+  if(read_conffile(CONFFILE_NAME)) {
+    perror(CONFFILE_NAME);
+    exit(1);
+  }
+
+  chg_scsi_conf = getconf_str(CNF_CHNGRFILE);
+  tape_device = getconf_str(CNF_TAPEDEV);
+
+  /* Get the configuration parameters */
+  /* 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)
+    {
+      fprintf(stderr, "%s open: of %s failed\n", get_pname(), chg_scsi_conf);
+      return 2;
+    }
+    confnum=atoi(tape_device);
+    if (chg.number_of_configs == 0)
+    {
+       fprintf(stderr,"%s: chg.conf[%d] == NULL\n",get_pname(), confnum);
+       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);
+    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);
+
+    if (NULL != chg.conf[confnum].slotfile)
+      slot_file = stralloc(chg.conf[confnum].slotfile);
+    else
+      slot_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);
+
+
+
+    /* 
+     * The changer device.
+     * If we can't open it fail with a message
+     */
+
+    if (OpenDevice(INDEX_CHANGER , changer_dev, "changer_dev", chg.conf[confnum].changerident) == 0)
+      {
+        int localerr = errno;
+        fprintf(stderr, "%s: open: %s: %s\n", get_pname(), 
+                changer_dev, strerror(localerr));
+        printf("%s open: %s: %s\n", "<none>", changer_dev, strerror(localerr));
+        dbprintf(("%s: open: %s: %s\n", get_pname(),
+                  changer_dev, strerror(localerr)));
+        return 2;
+      }
+
+    fd = INDEX_CHANGER;
+
+    /*
+     * The tape device.
+     * We need it for:
+     * eject if eject is set
+     * inventory (reading of the labels) if emubarcode (not yet)
+     */
+    if (tape_device != NULL)
+      {
+        if (OpenDevice(INDEX_TAPE, tape_device, "tape_device", chg.conf[confnum].tapeident) == 0)
+          {
+            dbprintf(("warning open of %s: failed\n",  tape_device));
+          }
+      }
+
+    /*
+     * This is for the status pages of the SCSI tape, nice to have but no must....
+     */
+    if (scsitapedevice != NULL)
+      {
+        if (OpenDevice(INDEX_TAPECTL, scsitapedevice, "scsitapedevice", chg.conf[confnum].tapeident) == 0)
+          {
+            dbprintf(("warning open of %s: failed\n", scsitapedevice));
+          }
+      }
+    
+
+    /*
+     * So if we need eject we need either an raw device to eject with an ioctl,
+     * or an SCSI device to send the SCSI eject.
+     */
+
+    if (need_eject != 0 )
+      {
+        if (pDev[INDEX_TAPE].avail == 0 && pDev[INDEX_TAPECTL].avail == 0)
+          {
+            printf("No device found for tape eject");
+            return(2);
+          }
+      }
+
+       
+    if ((chg.conf[confnum].end == -1) || (chg.conf[confnum].start == -1)){
+      slotcnt = get_slot_count(fd);
+      use_slots    = slotcnt;
+      slot_offset  = 0;
+    }
+
+    /*
+     * Now check if we have all what we need
+     * If either emubarcode is set or the changer support barcode
+     * we need an label file
+     */
+    
+    if ( chg.emubarcode == 1 || BarCode(INDEX_CHANGER) == 1) 
+      {
+        if (chg.labelfile == NULL)
+          {
+            printf("labelfile param not set in your config\n");
+            return(2);
+          }
+      }
+    
+    if (slot_file == NULL)
+      {
+        printf("slotfile param. not set in your config\n");
+        return(2);
+      }
+    
+    if (access(slot_file,R_OK|W_OK) != 0)
+      {
+        printf("slotfile %s does not exsist or is not read/write\n", slot_file);
+        return(2);
+      }
+
+  } else { /* if (strlen(tape_device)==1) */
+       printf("please check your config and use a config file for chg-scsi\n");
+       return(2);
+  }
+
+  drivecnt = get_drive_count(fd);
+
+  if (drive_num > drivecnt) {
+    printf("%s drive number error (%d > %d)\n", "<none>", 
+           drive_num, drivecnt);
+    fprintf(stderr, "%s: requested drive number (%d) greater than "
+            "number of supported drives (%d)\n", get_pname(), 
+            drive_num, drivecnt);
+    dbprintf(("%s: requested drive number (%d) greater than "
+              "number of supported drives (%d)\n", get_pname(), 
+              drive_num, drivecnt));
+    return 2;
+  }
+
+  loaded = drive_loaded(fd, drive_num);
+  target = -1;
+
+  switch(com.command_code) {
+/* This is only for the experts ;-) */
+  case COM_TRACE:
+       ChangerReplay(com.parameter);
+  break;
+/*
+*/
+  case COM_DUMPDB:
+    pbarcoderes->action = BARCODE_DUMP;
+    MapBarCode(chg.labelfile, pbarcoderes);
+    break;
+  case COM_STATUS:
+    ChangerStatus(com.parameter, chg.labelfile, BarCode(fd),slot_file, changer_dev, tape_device);
+    break;
+  case COM_LABEL: /* Update BarCode/Label mapping file */
+    pbarcoderes->action = BARCODE_PUT;
+    strcpy(pbarcoderes->data.voltag, com.parameter);
+    strcpy( pbarcoderes->data.barcode, pDTE[drive_num].VolTag);
+    MapBarCode(chg.labelfile, pbarcoderes);
+    printf("0 0 0\n");
+    break;
+
+    /*
+     * Inventory does an scan of the library and updates the mapping in the label DB
+     */
+  case COM_INVENTORY:
+    do_inventory = 1;                                     /* Tell the label check not to exit on label errors */
+    if (loaded)
+      {
+        oldtarget = get_current_slot(slot_file);
+        if (oldtarget < 0)
+          {
+            dbprintf(("COM_INVENTORY: get_current_slot %d\n", oldtarget));
+            oldtarget = find_empty(fd, slot_offset, use_slots);
+            dbprintf(("COM_INVENTORY: find_empty %d\n", oldtarget));
+          }
+
+        if (need_eject)
+          {
+            eject_tape(scsitapedevice, need_eject);
+          } else {
+            if (pDev[INDEX_TAPECTL].avail == 1 && pDev[INDEX_TAPE].avail == 1)
+              {
+                LogSense(INDEX_TAPE);
+              }
+          }
+
+        (void)unload(fd, drive_num, oldtarget);
+        if (ask_clean(scsitapedevice))
+          clean_tape(fd,tape_device,clean_file,drive_num,
+                     clean_slot,maxclean,time_file);
+      }
+    Inventory(chg.labelfile, drive_num, need_eject, 0, 0, clean_slot);
+    do_inventory = 0;                        /* If set on exit the labeldb will be set to invalid ..... */
+    break;
+   /*
+     * Search for the tape, the index is the volume label
+     */
+  case COM_SEARCH:
+    
+    /*
+     * If we have an barcode reader use
+     * this way
+     */
+    if (BarCode(fd) == 1 && emubarcode != 1)
+      {
+        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)
+          {
+            /*
+             * If both values are unset we have an problem
+             * so leave the program
+             */
+            if (pbarcoderes->data.slot == -1 && pbarcoderes->data.barcode == NULL)
+              {
+                printf("Label %s not found (1)\n",com.parameter);
+                endstatus = 2;
+                close(fd);
+                break;
+              }
+            
+
+            /*
+             * Let's see, if we got an barcode check if it is
+             * in the current inventory
+             */
+            if (pbarcoderes->data.barcode != NULL)
+              {
+                for (x = 0; x < STE; x++)
+                  {
+                    if (strcmp(pSTE[x].VolTag, pbarcoderes->data.barcode) == 0)
+                      {
+                        dbprintf(("search : found slot %d\n", x));
+                        target = x;
+                      }
+                  }
+                /*
+                 * Not found in the STE slots
+                 * my be in the DTE (tape)
+                 * 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++)
+                  {
+                    if (strcmp(pDTE[x].VolTag, pbarcoderes->data.barcode) == 0)
+                      {
+                        dbprintf(("search : found in tape %d\n", x));
+                        /*
+                         */
+                        if (x == drive_num) {
+                          oldtarget = get_current_slot(slot_file);
+                          printf("%d %s\n", oldtarget- slot_offset, tape_device);
+                          return(0);
+                        } else {
+                          printf("LABEL in wrong tape Unit\n");
+                          return(2);
+                        }
+                      }
+                  }
+                /*
+                 * not found, so do an exit...
+                 */               
+                if (target == -1)
+                  {
+                    printf("Label %s not found (2) \n",com.parameter);
+                    close(fd);
+                    endstatus = 2;
+                    break;
+                  }
+              }  /* if barcode[0] != 0 */
+
+            /*
+             * If we didn't find anything we will try the info
+             * from the DB. A reason for not finding anything in the inventory
+             * might be an unreadable barcode label
+             */
+            if (target == -1 && pbarcoderes->data.slot != -1)
+              {
+                target = pbarcoderes->data.slot;
+              }
+
+            /*
+             * OK, if target is still -1 do the exit
+             */
+            if (target == -1)
+              {
+                printf("Label %s not found (3)\n",com.parameter);
+                close(fd);
+                endstatus = 2;
+                break;
+              }
+          }
+               
+      }
+
+    /*
+     * And now if we have emubarcode set and no barcode reader
+     * use this one
+     */
+    if (emubarcode == 1 && BarCode(fd) != 1)
+      {
+        dbprintf(("search : look for %s\n", com.parameter));
+        pbarcoderes->action = FIND_SLOT;
+        pbarcoderes->data.slot = -1;
+        strcpy(pbarcoderes->data.voltag, com.parameter);
+
+        if (MapBarCode(chg.labelfile, pbarcoderes) == 1)
+          {
+            if (pbarcoderes->data.valid == 1)
+              {
+                target = pbarcoderes->data.slot;
+              } else {
+                printf("Barcode DB out of sync \n");
+                close(fd);
+                endstatus=2;
+                break;
+              }
+          } else {
+            printf("Label %s not found \n",com.parameter);
+            close(fd);
+            endstatus = 2;
+            break;
+          }
+      } 
+
+    /*
+     * The slot changing command
+     */
+  case COM_SLOT: 
+    if (target == -1)
+      {
+        if (is_positive_number(com.parameter)) {
+          if ((target = atoi(com.parameter))>=use_slots) {
+            printf("<none> no slot `%d'\n",target);
+            close(fd);
+            endstatus = 2;
+            break;
+          } else {
+            target = target+slot_offset;
+          }
+        } else {
+          param_index=0;
+          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);
+        }
+      }
+
+    if (loaded) {
+      oldtarget = get_current_slot(slot_file);
+      if (oldtarget < 0)
+        {
+          dbprintf(("COM_SLOT: get_current_slot %d\n", oldtarget));
+          oldtarget = find_empty(fd, slot_offset, use_slots);
+          dbprintf(("COM_SLOT: find_empty %d\n", oldtarget));
+        }
+      
+      /*
+       * TODO check if the request slot for the unload is empty
+       */
+
+       
+      if ((oldtarget)!=target) {
+        if (need_eject)
+          {
+            eject_tape(scsitapedevice, need_eject);
+          } else {
+            /*
+             * If we have an SCSI path to the tape and an raw io path
+             * try to read the Error Counter and the label
+             */
+            if (pDev[INDEX_TAPECTL].avail == 1 && pDev[INDEX_TAPE].avail == 1)
+              {
+                LogSense(INDEX_TAPE);
+              }
+          }
+
+        (void)unload(fd, drive_num, oldtarget);
+        if (ask_clean(scsitapedevice))
+          clean_tape(fd,tape_device,clean_file,drive_num,
+                     clean_slot,maxclean,time_file);
+        loaded=0;
+      }
+    }
+    
+    put_current_slot(slot_file, target);
+    
+    if (!loaded && isempty(fd, target)) {
+      printf("%d slot %d is empty\n",target-slot_offset,
+             target-slot_offset);
+      close(fd);
+      endstatus = 1;
+      break;
+    }
+
+    if (!loaded && param_index != SLOT_ADVANCE)
+      {
+        if (ask_clean(scsitapedevice))
+          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);  
+          close(fd);
+          endstatus = 2;
+          break;
+        }
+      }
+
+    if (need_sleep)
+      {
+        if (pDev[INDEX_TAPECTL].inqdone == 1)
+          {
+            if (Tape_Ready(INDEX_TAPECTL, need_sleep) == -1)
+              {
+                printf("tape not ready\n");
+                endstatus = 2;
+                break;
+              }
+          } else {
+            if (Tape_Ready(INDEX_TAPECTL, need_sleep) == -1)
+              {
+                printf("tape not ready\n");
+                endstatus = 2;
+                break;
+              }          
+        }
+      }
+
+    printf("%d %s\n", target-slot_offset, tape_device);
+    break;
+
+  case COM_INFO:
+    loaded = get_current_slot(slot_file);
+
+    if (loaded < 0)
+      {
+        loaded = find_empty(fd, slot_offset, use_slots);
+      }
+    loaded = loaded - slot_offset;
+      
+    printf("%d %d 1", loaded, use_slots);
+
+    if (BarCode(fd) == 1 || emubarcode == 1 || chg.havebarcode == 1)
+      {
+        printf(" 1\n");
+      } else {
+        printf(" 0\n");
+      }
+    break;
+
+  case COM_RESET:
+    target=get_current_slot(slot_file);
+
+    if (target < 0)
+    {
+      dbprintf(("COM_RESET: get_current_slot %d\n", target));
+      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);
+      
+      if (need_eject)
+        {
+          eject_tape(scsitapedevice, need_eject);
+        } else {
+          /*
+           * If we have an SCSI path to the tape and an raw io path
+           * try to read the Error Counter and the label
+           */
+          if (pDev[INDEX_TAPECTL].avail == 1 && pDev[INDEX_TAPE].avail == 1)
+            {
+              LogSense(INDEX_TAPE);
+            }
+        }
+      
+      (void)unload(fd, drive_num, target);
+      if (ask_clean(scsitapedevice))
+        clean_tape(fd,tape_device,clean_file,drive_num,clean_slot,
+                   maxclean,time_file);
+    }
+    
+    if (isempty(fd, slot_offset)) {
+      printf("0 slot 0 is empty\n");
+      close(fd);
+      endstatus = 1;
+      break;
+    }
+    
+    if (load(fd, drive_num, slot_offset) != 0) {
+      printf("%d slot %d move failed\n",drive_num,
+             slot_offset);  
+      close(fd);
+      put_current_slot(slot_file, slot_offset);
+      endstatus = 2;
+      break;
+    }
+    
+    put_current_slot(slot_file, slot_offset);
+    
+    if (need_sleep)
+      {
+        if (pDev[INDEX_TAPECTL].inqdone == 1)
+          {
+            if (Tape_Ready(INDEX_TAPECTL, need_sleep) == -1)
+              {
+                printf("tape not ready\n");
+                endstatus = 2;
+                break;
+              }
+          } else {
+            if (Tape_Ready(INDEX_TAPECTL, need_sleep) == -1)
+              {
+                printf("tape not ready\n");
+                endstatus = 2;
+                break;
+              }          
+          }
+      }
+    
+    printf("%d %s\n", slot_offset, tape_device);
+    break;
+
+  case COM_EJECT:
+    if (loaded) {
+      target=get_current_slot(slot_file);
+      if (target < 0)
+        {
+          dbprintf(("COM_EJECT: get_current_slot %d\n", target));
+          target = find_empty(fd, slot_offset, use_slots);
+          dbprintf(("COM_EJECT: find_empty %d\n", target));
+        }
+      
+      if (need_eject)
+        {
+          eject_tape(scsitapedevice, need_eject);
+        } else {
+          if (pDev[INDEX_TAPECTL].avail == 1 && pDev[INDEX_TAPE].avail == 1)
+            {
+              LogSense(INDEX_TAPE);
+            }
+        }
+
+
+      (void)unload(fd, drive_num, target);
+      if (ask_clean(scsitapedevice))
+        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");
+      endstatus = 1;
+    }
+    break;
+  case COM_CLEAN:
+    if (loaded) {
+      target=get_current_slot(slot_file);
+      if (target < 0)
+        {
+          dbprintf(("COM_CLEAN: get_current_slot %d\n", target));
+          target = find_empty(fd, slot_offset, use_slots);
+          dbprintf(("COM_CLEAN: find_empty %d\n",target));
+        }
+
+      if (need_eject)
+        {
+          eject_tape(scsitapedevice, need_eject);
+        } else {
+          if (pDev[INDEX_TAPECTL].avail == 1 && pDev[INDEX_TAPE].avail == 1)
+            {
+              LogSense(INDEX_TAPE);
+            }
+        }
+
+      (void)unload(fd, drive_num, target);
+    } 
+
+    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 */  
+/*   if (pChangerDev != NULL) */
+/*     close(pChangerDev->fd); */
+/*   if (pTapeDev != NULL) */
+/*     close(pTapeDev->fd); */
+
+/*   if (pTapeDevCtl != NULL) */
+/*     close(pTapeDevCtl->fd); */
+
+
+#endif
+  if (do_inventory == 1 && endstatus == 0 && chg.labelfile != NULL)
+    {
+      if ( chg.autoinv == 1)
+        {
+          DebugPrint(DEBUG_INFO,SECTION_INFO, "Do an inventory \n");
+          Inventory(chg.labelfile, drive_num , chg.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));
+          pbarcoderes->action = RESET_VALID;
+          MapBarCode(chg.labelfile,pbarcoderes);
+        }
+    }
+
+  DebugPrint(DEBUG_INFO,SECTION_INFO,"Exit status -> %d\n", endstatus);
+  dbclose();
+  return endstatus;
+}
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * tab-width: 4
+ * End:
+ */
+
diff --git a/changer-src/chg-zd-mtx.sh.in b/changer-src/chg-zd-mtx.sh.in
new file mode 100644 (file)
index 0000000..6cf5b18
--- /dev/null
@@ -0,0 +1,1294 @@
+#!/bin/sh 
+#
+# Exit Status:
+# 0 Alles Ok
+# 1 Illegal Request
+# 2 Fatal Error
+#
+# Contributed by Eric DOUTRELEAU <Eric.Doutreleau@int-evry.fr>
+# This is supposed to work with Zubkoff/Dandelion version of mtx
+#
+# Modified by Joe Rhett <jrhett@isite.net>
+# to work with MTX 1.2.9 by Eric Lee Green http://mtx.sourceforge.net
+#
+# Modified by Jason Hollinden <jhollind@sammg.com> on 13-Feb-2001
+# to work with MTX 1.2.10, >9 slots, has barcode support, and works with
+# multiple configs at once.
+# NOTE:  Only tested the 2 additions with an ADIC Scalar 100.
+
+################################################################################
+# Here are the things you need to do and know to configure this script:
+#
+#   * Figure out what the robot device name is and what the tape drive
+#     device name is.  They will be different!
+#
+#     You cannot send robot commands to a tape drive and vice versa.
+#     Both should respond to "mtx -f /dev/... inquiry".  Hopefully,
+#     that output will make it obvious which is which.
+#
+#     For instance, here is what mtx has to say about my current robot:
+#
+#       Product Type: Medium Changer
+#       Vendor ID: 'ATL     '
+#       Product ID: 'ACL2640 206     '
+#       Revision: '2A5A'
+#       Attached Changer: No
+#
+#     and here is what it says about a tape drive:
+#
+#       Product Type: Tape Drive
+#       Vendor ID: 'Quantum '
+#       Product ID: 'DLT4000         '
+#       Revision: 'CD50'
+#       Attached Changer: No
+#
+#     Note the "Product Type" value makes it clear which is which.
+#
+#     If it is not obvious, "mf -f /dev/... rewind" should be happy when
+#     talking to a (loaded) tape drive but the changer should give some
+#     kind of error.  Similarly, "mtx -f /dev/... status" should show good
+#     results with the changer but fail with a tape drive device name.
+#
+#     Once you have this figured out, set "changerdev" in amanda.conf
+#     to the changer device and "tapedev" to the tape device.
+#
+#   * Find out what the first and last storage slots are.  Running
+#     "mtx -f /dev/... status" should give you something like this
+#     (although the output will vary widely based on the version of mtx
+#     and the specifics of your robot):
+#
+#        Storage Changer /dev/changer:1 Drives, 9 Slots ( 0 Import/Export )
+#      Data Transfer Element 0:Empty
+#            Storage Element 1:Full :VolumeTag=SR0001
+#            Storage Element 2:Full :VolumeTag=SR0002
+#            Storage Element 3:Full :VolumeTag=SR0003
+#            Storage Element 4:Full :VolumeTag=SR0004
+#            Storage Element 5:Full :VolumeTag=SR0005
+#            Storage Element 6:Full :VolumeTag=SR0006
+#            Storage Element 7:Full :VolumeTag=SR0007
+#            Storage Element 8:Full :VolumeTag=SR0008
+#            Storage Element 9:Full :VolumeTag=SR0009
+#
+#     This says the first storage slot (element) is "1" and the last
+#     is "9".  If you allocate the entire robot to Amanda, you do not need
+#     to set the "firstslot" or "lastslot" configuration file variables --
+#     the script will compute these values for you.
+#
+#     You do not have to allocate all of the slots for Amanda use,
+#     but whatever slots you use must be contiguous (i.e. 4 through 9
+#     in the above would be OK but 1, 2, 5, 6, 9 would not).  The one
+#     exception to this is that if one of the slots contains a cleaning
+#     cartridge, it may be in any slot (Amanda will just skip over it if
+#     it is between firstslot and lastslot).
+#
+#   * Speaking of cleaning cartridges, if you have a storage slot dedicated
+#     to one, figure out what slot it is in.  That slot number will go in
+#     the "cleanslot" variable.
+#
+#     Also, decide if you want the changer script to automatically run
+#     the cleaning tape through the drive after every so many mounts,
+#     and how many mounts you want to do between cleanings.  If you
+#     want the script to do this, set the "autoclean" variable to 1 and
+#     the "autocleancount" to the number of mounts between cleanings.
+#     If you do not want to do automatic cleanings (including not having
+#     a cleaning cartridge in the robot), set "autoclean" to 0.
+#
+#     Note that only a count of mounts is used to determine when it is
+#     time to clean.  The script does not try to detect if the drive is
+#     requesting cleaning, or how much the drive was used on a given
+#     mount.
+#
+#   * If you tell Amanda about a cleaning cartridge, whether for automatic
+#     operation or manual (amtape <config> clean), you must also tell
+#     the script how long it takes to run the cleaning cycle.  It is
+#     impossible for the script to determine when the cleaning operation
+#     is done, so the "cleancycle" variable is the number of seconds
+#     the longest cleaning operation takes (you'll just have to figure
+#     this out by watching it a few times, or maybe finding it in a tape
+#     drive hardware manual).  The script will sleep for this length of
+#     time whenever the cleaning tape is referenced.  The default is 120
+#     seconds (two minutes).
+#
+#   * Figure out the drive slot number.  By default, it is set to 0.
+#     In the example above, the tape drive ("Data Transfer Element")
+#     is in slot 0. If your drive slot is not 0, you
+#     need to set the drive slot number with the "driveslot" variable.
+#
+#   * Figure out whether your robot has a barcode reader and whether
+#     your version of mtx supports it.  If you see "VolumeTag" entries
+#     in the "mtx -f /dev/xxx status" output you did above, you have
+#     a reader and mtx can work with it, so you may set the "havereader"
+#     variable to 1.  The default is 0 (do not use a reader).
+#
+#   * Pick any tape to load and then determine if the robot can put it
+#     away directly or whether an "offline" must be done first.
+#
+#     With the tape still mounted and ready, try to put the tape away
+#     with "mtx".  If you get some kind of error, which is the most
+#     common response, try "mt -f /dev/... offline", wait for the drive
+#     to unload and make sure the robot takes no action on its own to
+#     store the tape.  Assuming it does not, try the "mtx" command again
+#     to store the tape.
+#
+#     If you had to issue the "mt -f /dev/... offline" before you could
+#     use "mtx" to store the tape, set the "offline_before_unload"
+#     variable to 1.  If "mtx" unloaded the drive and put the tape away
+#     all by itself, set it to 0.
+#
+#   * Some drives and robots require a small delay between unloading the
+#     tape and instructing the robot to move it back to storage.
+#     For instance, if you try to grab the tape too soon on an ATL robot
+#     with DLT tape drives, it will rip the leader out of the drive and
+#     require sincerely painful hardware maintenance.
+#
+#     If you need a little delay, set the "unloadpause" variable to
+#     the number of seconds to wait before trying to take a tape from
+#     a drive back to storage.  The default is 0.
+#
+#   * Some drives also require a short pause after loading, or the drive
+#     will return an I/O error during a test to see if it's online (which
+#     this script uses "mt rewind" to test).  My drives don't recover from
+#     this, and must be reloaded before they will come online after failing
+#     such a test.  For this reason there is an "initial_poll_delay"
+#     variable which will pause for a certain number of seconds before
+#     looping through the online test for the first time.  The default is 0.
+####
+
+####
+# Now you are ready to set up the variables in the changer configuration
+# file.
+#
+# All variables are in "changerfile".conf where "changerfile" is set
+# in amanda.conf.  For example, if amanda.conf has:
+#
+#      changerfile="/etc/amanda/Dailyset1/CHANGER"
+#
+# the variables must be in "/etc/amanda/Dailyset1/CHANGER.conf".
+#
+# If "changerfile" is a relative path, it is relative to the directory
+# that contains amanda.conf.  That also happens to be the directory Amanda
+# makes current before running this script.
+#
+# Here is a commented out example file with all the variables and showing
+# their default value (if any):
+####
+# firstslot=?              #### First storage slot (element) -- required
+# lastslot=?               #### Last storage slot (element) -- required
+# cleanslot=-1             #### Slot with cleaner tape -- default is "-1"
+#                          #### Set negative to indicate no cleaner available
+# driveslot=0              #### Drive slot number.  Defaults to 0
+#                          #### Use the 'Data Transfer Element' you want
+#
+#   # Do you want to clean the drive after a certain number of accesses?
+#   # NOTE - This is unreliable, since 'accesses' aren't 'uses', and we
+#   #        have no reliable way to count this.  A single amcheck could
+#   #        generate as many accesses as slots you have, plus 1.
+#   # ALSO NOTE - many modern tape loaders handle this automatically.
+#
+# autoclean=0              #### Set to '1' or greater to enable
+#
+# autocleancount=99        #### Number of access before a clean.
+#
+# havereader=0             #### If you have a barcode reader, set to 1.
+#
+# offline_before_unload=0   #### Does your robot require an
+#                          #### 'mt offline' before mtx unload?
+#
+# poll_drive_ready=NN      #### Time (seconds) between tests to see if
+#                          #### the tape drive has gone ready (default: 3).
+#
+# max_drive_wait=NN        #### Maximum time (seconds) to wait for the
+#                          #### tape drive to become ready (default: 120).
+#
+# initial_poll_delay=NN            #### initial delay after load before polling for
+#                          #### readiness
+####
+
+####
+# Now it is time to test the setup.  Do all of the following in the
+# directory that contains the amanda.conf file, and do all of it as
+# the Amanda user.
+#
+#   * Run this:
+#
+#       .../chg-zd-mtx -info
+#       echo $?             #### (or "echo $status" if you use csh/tcsh)
+#
+#     You should get a single line from the script like this (the actual
+#     numbers will vary):
+#
+#       5 9 1 1
+#
+#     The first number (5) is the "current" slot.  This may or may not be
+#     the slot actually loaded at the moment (if any).  It is the slot
+#     Amanda will try to use next.
+#
+#     The second number (9) is the number of slots.
+#
+#     The third number will always be "1" and indicates the changer is
+#     capable of going backward.
+#
+#     The fourth number is optional.  If you set $havereader to 1, it
+#     will be "1", otherwise it will not be present.
+#
+#     The exit code ($? or $status) should be zero.
+#
+#   * Run this:
+#
+#       .../chg-zd-mtx -reset
+#       echo $?
+#
+#     The script should output a line like this:
+#
+#       1 /dev/rmt/0mn
+#
+#     The number at the first should match $firstslot.  The device name
+#     after that should be your tape device.
+#
+#     The exit code ($? or $status) should be zero.
+#
+#   * Run this:
+#
+#       .../chg-zd-mtx -slot next
+#       echo $?
+#
+#     The script should output a line like this:
+#
+#       2 /dev/rmt/0mn
+#
+#     The number at the first should be one higher than $firstslot.
+#     The device name after that should be your tape device.
+#
+#     The exit code ($? or $status) should be zero.
+#
+#   * Run this:
+#
+#       .../chg-zd-mtx -slot current
+#       echo $?
+#
+#     Assuming the tape is still loaded from the previous test, the
+#     robot should not move and the script should report the same thing
+#     the previous command did.
+#
+#   * If you continue to run "-slot next" commands, the robot should load
+#     each tape in turn then wrap back around to the first when it
+#     reaches $lasttape.  If $cleanslot is within the $firstslot to
+#     $lastslot range, the script will skip over that entry.
+#
+#   * Finally, try some of the amtape commands and make sure they work:
+#
+#       amtape <config> reset
+#       amtape <config> slot next
+#       amtape <config> slot current
+#
+#   * If you set $havereader non-zero, now would be a good time to create
+#     the initial barcode database:
+#
+#       amtape <config> update
+####
+
+################################################################################
+# To debug this script, first look in @AMANDA_DBGDIR@.  The script
+# uses one of two log files there, depending on what version of Amanda
+# is calling it.  It may be chg-zd-mtx.YYYYMMDD*.debug, or it may be
+# changer.debug.driveN where 'N' is the drive number.
+#
+# If the log file does not help, try running the script, **as the Amanda
+# user**, in the amanda.conf directory with whatever set of args the log
+# said were used when you had a problem.  If nothing else useful shows up
+# in the output, try running the script with the DEBUG environment variable
+# set non-null, e.g.:
+#
+#      env DEBUG=yes .../chg-zd-mtx ...
+################################################################################
+
+################################################################################
+# You may need to customize these things
+################################################################################
+
+MT=@MT@
+MTF=@MT_FILE_FLAG@
+MTX=@MTX@
+
+################################################################################
+# No user-level customization should be required beyond this point.
+################################################################################
+
+test -n "$DEBUG" && set -x
+TMPDIR="@AMANDA_TMPDIR@"
+DBGDIR="@AMANDA_DBGDIR@"
+
+argv0=$0
+myname=`expr "$argv0" : '.*/\(.*\)'`
+
+config=`pwd 2>/dev/null`
+config=`expr "$config" : '.*/\(.*\)'`
+
+###
+# Functions to write a new log file entry and append more log information.
+###
+
+ds=`date '+%H:%M:%S' 2>/dev/null`
+if [ $? -eq 0  -a  -n "$ds" ]; then
+       logprefix=`echo "$ds" | sed 's/./ /g'`
+else
+       logprefix=""
+fi
+
+LogAppend() {
+       if [ -z "$logprefix" ]; then
+               echo "$@" >> $DBGFILE
+       else
+               echo "$logprefix" "$@" >> $DBGFILE
+       fi
+}
+
+Log() {
+       if [ -z "$logprefix" ]; then
+               echo "===" "`date`" "===" >> $DBGFILE
+               echo "$@" >> $DBGFILE
+       else
+               ds=`date '+%H:%M:%S' 2>/dev/null`
+               echo "$ds" "$@" >> $DBGFILE
+       fi
+}
+
+###
+# Common exit function.
+#
+#   $1 = exit code
+#   $2 = slot result
+#   $3 = additional information (error message, tape devive, etc)
+###
+
+internal_call=0
+Exit() {
+       if [ $internal_call -gt 0 ]; then
+               call_type=Return
+       else
+               call_type=Exit
+       fi
+       code=$1
+       shift
+       exit_slot=$1
+       shift
+       exit_answer="$@"
+       Log $call_type "($code)" "->" "$exit_slot" "$@"
+       echo "$exit_slot" "$@"
+       if [ $call_type = Return ]; then
+               return $code
+       fi
+       amgetconf$SUF dbclose.$argv0:$DBGFILE > /dev/null 2>&1
+       exit $code
+}
+
+###
+# Function to run another command and log it.
+###
+
+Run() {
+       Log Running: "$@"
+       rm -f $stdout $stderr
+       "$@" > $stdout 2> $stderr
+       exitcode=$?
+       Log Exit code: $exitcode
+       if [ -s $stdout ]
+       then
+               LogAppend Stdout:
+               cat $stdout >> $DBGFILE
+       fi
+       if [ -s $stderr ]
+       then
+               LogAppend Stderr:
+               cat $stderr >> $DBGFILE
+       fi
+       cat $stdout
+       cat $stderr 1>&2
+       return $exitcode
+}
+
+###
+# Return success if the arg is numeric.
+###
+
+IsNumeric() {
+       test -z "$1" && return 1
+       x="`expr "$1" : '\([-0-9][0-9]*\)' 2>/dev/null`"
+       return `expr X"$1" != X"$x"`
+}
+
+###
+# Run $MTX status unless the previous output is still valid.
+###
+
+mtx_status_valid=0
+get_mtx_status() {
+       test -n "$DEBUG" && set -x
+       if [ $mtx_status_valid -ne 0 ]; then
+               return 0
+       fi
+       rm -f $mtx_status
+       Run $MTX status > $mtx_status 2>&1
+       status=$?
+       if [ $status -eq 0 ]; then
+               mtx_status_valid=1
+       fi
+       return $status
+}
+
+###
+# Determine the slot currently loaded.  Set $loadedslot to the slot
+# currently loaded, or "-1", and $loadedbarcode to the corresponding
+# barcode (or nothing).
+###
+
+get_loaded_info() {
+       test -n "$DEBUG" && set -x
+       get_mtx_status
+
+       set x `sed -n '
+/^Data Transfer Element:Empty/                         {
+    s/.*/-1/p
+    q
+}
+/^Data Transfer Element '$driveslot':Empty/            {
+    s/.*/-1/p
+    q
+}
+/^Data Transfer Element:Full.*:VolumeTag/              {
+    s/.*(Storage Element \([0-9][0-9]*\) Loaded):VolumeTag *= *\([^    ]*\)/\1 \2/p
+    q
+}
+/^Data Transfer Element '$driveslot':Full.*:VolumeTag/ {
+    s/.*(Storage Element \([0-9][0-9]*\) Loaded):VolumeTag *= *\([^    ]*\)/\1 \2/p
+    q
+}
+/^Data Transfer Element:Full/                          {
+    s/.*(Storage Element \([0-9][0-9]*\) Loaded)\(.*\)/\1/p
+    q
+}
+/^Data Transfer Element '$driveslot':Full/             {
+    s/.*(Storage Element \([0-9][0-9]*\) Loaded)\(.*\)/\1/p
+    q
+}
+' < $mtx_status 2>&1`
+       shift                                   # get rid of the "x"
+       loadedslot=$1
+       loadedbarcode=$2
+
+       if [ -z "$loadedslot" ]; then
+               Exit 2 "<none>" "could not determine current slot, are you sure your drive slot is $driveslot"
+               return $?                       # in case we are internal
+       fi
+       if IsNumeric "$loadedslot" ; then
+               :
+       else
+               Exit 2 \
+                    "<none>" \
+                    "currently loaded slot ($loadedslot) not numeric"
+               return $?                       # in case we are internal
+       fi
+       Log       "STATUS   -> currently loaded slot = $loadedslot"
+       LogAppend "         -> currently loaded barcode = \"$loadedbarcode\""
+}
+
+###
+# Get a list of slots between $firstslot and $lastslot, if they are set.
+# If they are not set, set them to the first and last slot seen on the
+# assumption the entire robot is to be used (???).
+###
+
+slot_list=
+get_slot_list() {
+       test -n "$DEBUG" && set -x
+       if [ -n "$slot_list" ]; then
+               return
+       fi
+       get_mtx_status
+       slot_list=`sed -n '
+/^Data Transfer Element:Full/                          {
+    s/.*(Storage Element \([0-9][0-9]*\) Loaded)\(.*\)/\1/p
+}
+/^Data Transfer Element '$driveslot':Full/             {
+    s/.*(Storage Element \([0-9][0-9]*\) Loaded)\(.*\)/\1/p
+}
+/^[    ]*Storage Element \([0-9][0-9]*\):Full/         {
+    s/.*Storage Element \([0-9][0-9]*\):.*/\1/p
+}
+' < $mtx_status 2>&1 | grep -v "^${cleanslot}\$" | sort -n`
+       slot_list=`echo $slot_list`             # remove the newlines
+       if [ $firstslot -lt 0 -o $lastslot -lt 0 ]; then
+               last=$lastslot
+               for slot in $slot_list; do
+                       if [ $firstslot -lt 0 ]; then
+                               Log "SLOTLIST -> firstslot set to $slot"
+                               firstslot=$slot
+                       fi
+                       if [ $lastslot -lt 0 ]; then
+                               last=$slot
+                       fi
+               done
+               if [ $lastslot -lt 0 -a $last -ge 0 ]; then
+                       Log "SLOTLIST -> lastslot set to $last"
+                       lastslot=$last
+               fi
+               if [ $firstslot -lt 0 ]; then
+                       Exit 2 \
+                            "<none>" \
+                            "cannot determine first slot"
+                       return $?               # in case we are internal
+               elif [ $lastslot -lt 0 ]; then
+                       Exit 2 \
+                            "<none>" \
+                            "cannot determine last slot"
+                       return $?               # in case we are internal
+               fi
+       fi
+       amanda_slot_list=
+       for slot in $slot_list; do
+               if [ $slot -ge $firstslot -a $slot -le $lastslot ]; then
+                       amanda_slot_list="$amanda_slot_list $slot"
+               fi
+       done
+       if [ -z "$amanda_slot_list" ]; then
+               Exit 2 \
+                    "<none>" \
+                    "no slots available"
+               return $?                       # in case we are internal
+       fi
+       slot_list="$amanda_slot_list"
+}
+
+# Paths
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+# try to hit all the possibilities here
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+DBGFILE=`amgetconf$SUF dbopen.$argv0 2>/dev/null | grep -v BUGGY`
+if [ -z "$DBGFILE" ]
+then
+       DBGFILE=/dev/null                       # will try this again below
+fi
+
+changerfile=`amgetconf$SUF changerfile 2>/dev/null | grep -v BUGGY`
+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`
+if [ -z "$tape" ]; then
+       Exit 2 \
+            "<none>" \
+            "tapedev may not be empty"
+elif [ $tape = "/dev/null" -o `expr "$tape" : 'null:'` -eq 5 ]; then
+       Exit 2 \
+            "<none>" \
+            "tapedev ($tape) may not be the null device"
+fi
+TAPE=`amgetconf$SUF changerdev 2>/dev/null | grep -v BUGGY`
+if [ -z "$TAPE" ]; then
+       Exit 2 \
+            "<none>" \
+            "changerdev may not be empty"
+elif [ $TAPE = "/dev/null" ]; then
+       Exit 2 \
+            "<none>" \
+            "changerdev ($TAPE) may not be the null device"
+fi
+export TAPE                                    # for mtx command
+
+#### Set up the various config files.
+
+configfile=$changerfile.conf
+cleanfile=$changerfile-clean
+accessfile=$changerfile-access
+slotfile=$changerfile-slot
+labelfile=$changerfile-barcodes
+[ ! -s $cleanfile ] && echo 0 > $cleanfile
+[ ! -s $accessfile ] && echo 0 > $accessfile
+[ ! -s $slotfile ] && echo -1 > $slotfile
+[ ! -f $labelfile ] && > $labelfile
+cleancount=`cat $cleanfile`
+accesscount=`cat $accessfile`
+
+#### Dig out of the config file what is needed
+
+varlist=
+varlist="$varlist firstslot"
+varlist="$varlist lastslot"
+varlist="$varlist cleanslot"
+varlist="$varlist cleancycle"
+varlist="$varlist OFFLINE_BEFORE_UNLOAD"       # old name
+varlist="$varlist offline_before_unload"
+varlist="$varlist unloadpause"
+varlist="$varlist AUTOCLEAN"                   # old name
+varlist="$varlist autoclean"
+varlist="$varlist autocleancount"
+varlist="$varlist havereader"
+varlist="$varlist driveslot"
+varlist="$varlist poll_drive_ready"
+varlist="$varlist initial_poll_delay"
+varlist="$varlist max_drive_wait"
+
+for var in $varlist
+do
+       val="`cat $configfile 2>/dev/null | sed -n '
+# Ignore comment lines (anything starting with a #).
+/^[    ]*#/d
+# Find the first var=val line in the file, print the value and quit.
+/^[    ]*'$var'[       ]*=[    ]*\([^  ][^     ]*\).*/ {
+       s/^[    ]*'$var'[       ]*=[    ]*\([^  ][^     ]*\).*/\1/p
+       q
+}
+'`"
+       eval $var=\"$val\"
+done
+
+# Deal with driveslot first so we can get DBGFILE set if we are still
+# using the old amgetconf.
+
+if [ -z "$driveslot" ]; then
+       driveslot=0;
+fi
+
+# Get DBGFILE set if it is not already.
+
+if [ $DBGFILE = /dev/null ]; then
+       if [ -d "$DBGDIR" ]; then
+               DBGFILE=$DBGDIR/changer.debug.drive$driveslot
+       else
+               DBGFILE=/dev/null
+       fi
+       Log === Start "`date`" ===
+fi
+if [ -z "$driveslot" ]; then
+       Exit 2 \
+            "<none>" \
+            "cannot determine drive slot from $tape"
+fi
+
+stdout=$TMPDIR/$myname.1.$$
+stderr=$TMPDIR/$myname.2.$$
+mtx_status=$TMPDIR/$myname.status.$$
+trap "rm -f $stdout $stderr $mtx_status" 0     # exit cleanup
+
+Log "Using config file $configfile"
+
+# Log the argument list.
+
+Log "Arg info:"
+LogAppend "\$# = $#"
+i=0
+LogAppend "\$$i = \"$argv0\""
+for arg in "$@"; do
+       i=`expr $i + 1`
+       LogAppend "\$$i = \"$arg\""
+done
+
+# Set the default config values for those not in the file.  Log the
+# results and make sure each is valid (numeric).
+
+firstslot=${firstslot:-'-1'}                           # default: mtx status
+lastslot=${lastslot:-'-1'}                             # default: mtx status
+cleanslot=${cleanslot:-'-1'}                           # default: -1
+cleancycle=${cleancycle:-'120'}                                # default: two minutes
+if [ -z "$offline_before_unload" -a -n "$OFFLINE_BEFORE_UNLOAD" ]; then
+       offline_before_unload=$OFFLINE_BEFORE_UNLOAD    # (old name)
+fi
+offline_before_unload=${offline_before_unload:-'0'}    # default: 0
+unloadpause=${unloadpause:-'0'}                                # default: 0
+if [ -z "$autoclean" -a -n "$AUTOCLEAN" ]; then
+       autoclean=$AUTOCLEAN                            # (old name)
+fi
+autoclean=${autoclean:-'0'}                            # default: 0
+autocleancount=${autocleancount:-'99'}                 # default: 99
+havereader=${havereader:-'0'}                          # default: 0
+poll_drive_ready=${poll_drive_ready:-'3'}              # default: three seconds
+initial_poll_delay=${initial_poll_delay:-'0'}          # default: zero zeconds
+max_drive_wait=${max_drive_wait:-'120'}                        # default: two minutes
+
+get_slot_list
+
+Log "Config info:"
+for var in $varlist; do
+       if [ $var = "OFFLINE_BEFORE_UNLOAD" ]; then
+               continue                        # old name
+       elif [ $var = "AUTOCLEAN" ]; then
+               continue                        # old name
+       fi
+       eval val=\"'$'$var\"
+       if [ -z "$val" ]; then
+               Exit 2 \
+                    "<none>" \
+                    "$var missing in $configfile"
+       fi
+       if IsNumeric "$val" ; then
+               :
+       else
+               Exit 2 \
+                    "<none>" \
+                    "$var ($val) not numeric in $configfile"
+       fi
+       LogAppend $var = \"$val\"
+done
+
+# Run the rest of the config file sanity checks.
+
+if [ $firstslot -gt $lastslot ]; then
+       Exit 2 \
+            "<none>" \
+            "firstslot ($firstslot) greater than" \
+            "lastslot ($lastslot) in $configfile"
+fi
+if [ $autoclean -ne 0 -a $cleanslot -lt 0 ]; then
+       Exit 2 \
+            "<none>" \
+            "autoclean set but cleanslot not valid ($cleanslot)"
+fi
+
+# Set up the current slot
+
+currentslot=`cat $slotfile`
+if IsNumeric "$currentslot" ; then
+       if [ $currentslot -lt $firstslot ]; then
+               Log "SETUP    -> current slot $currentslot" \
+                                "less than $firstslot ..." \
+                                "resetting to $firstslot"
+               currentslot=$firstslot
+       elif [ $currentslot -gt $lastslot ]; then
+               Log "SETUP    -> current slot $currentslot" \
+                                "greater than $lastslot ..." \
+                                "resetting to $lastslot"
+               currentslot=$lastslot
+       fi
+else
+       Log "SETUP    -> contents of $slotfile ($currentslot) invalid," \
+                        "setting current slot to first slot ($firstslot)"
+       currentslot=$firstslot
+fi
+
+found_current=0
+first_slot_in_list=-1
+next_slot_after_current=-1
+for slot in $slot_list; do
+       if [ $first_slot_in_list -lt 0 ]; then
+               first_slot_in_list=$slot        # in case $firstslot is missing
+       fi
+       if [ $slot -eq $currentslot ]; then
+               found_current=1
+               break
+       elif [ $slot -gt $currentslot ]; then
+               next_slot_after_current=$slot   # $currentslot is missing
+               break
+       fi
+done
+if [ $found_current -eq 0 ]; then
+       if [ $next_slot_after_current -lt 0 ]; then
+               new_currentslot=$first_slot_in_list
+       else
+               new_currentslot=$next_slot_after_current
+       fi
+       Log "WARNING  -> current slot $currentslot not available," \
+                        "setting current slot to next slot ($new_currentslot)"
+       currentslot=$new_currentslot
+fi
+
+# More routines.
+
+###
+# Eject the current tape and put it away.
+###
+
+eject() {
+       test -n "$DEBUG" && set -x
+       Log "EJECT    -> ejecting tape from $tape"
+       get_loaded_info 
+       if [ $loadedslot -gt 0 ]; then
+               Log "EJECT    -> moving tape from drive $driveslot" \
+                                "to storage slot $loadedslot"
+               if [ $offline_before_unload -ne 0 ]; then
+                       Run $MT $MTF $tape offline > /dev/null 2>&1
+               fi
+               sleep $unloadpause
+               result=`Run $MTX unload $loadedslot $driveslot 2>&1`
+               status=$?
+               Log "         -> status $status, result \"$result\""
+               mtx_status_valid=0
+               if [ $status -ne 0 ]; then
+                       answer="$result"
+                       code=2
+               else
+                       answer="$tape"
+                       code=0
+               fi
+       else
+               answer="Drive was not loaded"
+               code=1
+       fi
+       Exit $code "$loadedslot" "$answer"
+       return $?                               # in case we are internal
+}
+
+###
+# Reset the robot back to the first slot.
+###
+
+reset() {
+       test -n "$DEBUG" && set -x
+       Log "RESET    -> loading tape from slot $firstslot" \
+                        "to drive $driveslot ($tape)"
+       # Call loadslot without doing it as an internal and let it finish
+       # things up.
+       loadslot $firstslot
+       # NOTREACHED
+       Exit 2 "<none>" "reset: should not get here"
+       return $?                               # in case we are internal
+}
+
+###
+# Unload the current tape (if necessary) and load a new one (unless
+# "advance").  If no tape is loaded, get the value of "current" from
+# $slotfile.
+###
+
+loadslot() {
+       test -n "$DEBUG" && set -x
+       if [ $# -lt 1 ]; then
+               Exit 2 "<none>" "Missing -slot argument"
+               return $?                       # in case we are internal
+       fi
+       whichslot=$1
+       Log "LOADSLOT -> load drive $driveslot ($tape) from slot $whichslot"
+
+       numeric=`echo $whichslot | sed 's/[^0-9]//g'`
+       case $whichslot in
+       current|prev|next|advance)
+               find_slot=$currentslot
+               ;;
+       first)
+               find_slot=$firstslot
+               ;;
+       last)
+               find_slot=$lastslot
+               ;;
+       $numeric)
+               find_slot=$numeric
+               ;;
+       clean)
+               find_slot=$cleanslot
+               ;;
+       *)
+               Exit 2 "<none>" "Illegal slot: \"$whichslot\""
+               return $?                       # in case we are internal
+               ;;
+       esac
+
+       # Find the requested slot in the slot list.  By loading the "set"
+       # command with multiple copies, we guarantee that if the slot is
+       # found, we can look both forward and backward without running
+       # off the end.  Putting $cleanslot at the end allows us to find
+       # that slot since it is not in $slot_list.
+       get_slot_list
+       set x $slot_list $slot_list $slot_list $cleanslot
+       shift                                   # get rid of the "x"
+       prev_slot=$1
+       shift
+       while [ $# -gt 0 ]; do
+               if [ $1 -eq $find_slot ]; then
+                       break
+               fi
+               prev_slot=$1
+               shift
+       done
+       if [ $# -le 0 ]; then
+               Exit 2 \
+                    "<none>" \
+                    "Cannot find slot $find_slot" \
+                    "in slot list ($slot_list)"
+               return $?                       # in case we are internal
+       fi
+
+       # Determine the slot to load.
+       case $whichslot in
+       next|advance)
+               shift
+               loadslot=$1
+               ;;
+       prev)
+               loadslot=$prev_slot
+               ;;
+       *)
+               loadslot=$find_slot
+       esac
+
+       # If the desired slot is already loaded, we are done.  Only update
+       # current slot if this is not the cleaning slot.
+       get_loaded_info
+       if [ $loadslot = $loadedslot ]; then
+               if [ $loadslot -ne $cleanslot ]; then
+                       rm -f $slotfile
+                       echo $loadslot > $slotfile
+               fi
+               Exit 0 "$loadedslot" "$tape"
+               return $?                       # in case we are internal
+       fi
+
+       # If we are loading the cleaning tape, bump the cleaning count
+       # and reset the access count.  Otherwise, bump the access count
+       # and see if it is time to do a cleaning.
+       if [ $loadslot = $cleanslot ]; then
+               rm -f $cleanfile $accessfile
+               expr $cleancount + 1 > $cleanfile
+               echo 0 > $accessfile
+       else
+               rm -f $accessfile
+               expr $accesscount + 1 > $accessfile
+               if [ $autoclean -ne 0 -a $accesscount -gt $autocleancount ]
+               then
+                       internal_call=`expr $internal_call + 1`
+                       loadslot clean > /dev/null 2>&1
+                       status=$?
+                       internal_call=`expr $internal_call - 1`
+                       if [ $status -ne 0 ]; then
+                               Exit $status "$loadslot" "$exit_answer"
+                               return $?       # in case we are internal
+                       fi
+
+                       # Slot $cleanslot might contain an ordinary tape
+                       # rather than a cleaning tape.  A cleaning tape
+                       # *MIGHT* auto-eject; an ordinary tape does not.
+                       # We therefore have to read the status again to
+                       # check what actually happened.
+                       mtx_status_valid=0
+                       get_loaded_info
+               fi
+       fi
+
+       # Unload whatever tape is in the drive.
+       internal_call=`expr $internal_call + 1`
+       eject > /dev/null 2>&1
+       status=$?
+       internal_call=`expr $internal_call - 1`
+       if [ $status -gt 1 ]; then
+               Exit $status "$exit_slot" "$exit_answer"
+               return $?                       # in case we are internal
+       fi
+
+       # If we were doing an "advance", we are done.
+       if [ $whichslot = advance ]; then
+               if [ $loadslot -ne $cleanslot ]; then
+                       rm -f $slotfile
+                       echo $loadslot > $slotfile
+               fi
+               Exit 0 "$loadslot" "/dev/null"
+               return $?                       # in case we are internal
+       fi
+
+       # Load the tape, finally!
+       Log "LOADSLOT -> loading tape from slot $loadslot" \
+                        "to drive $driveslot ($tape)"
+       result=`Run $MTX load $loadslot $driveslot 2>&1`
+       status=$?
+       Log "         -> status $status, result \"$result\""
+       mtx_status_valid=0
+       if [ $status -ne 0 ]; then
+               Exit 2 "$loadslot" "$result"
+               return $?                       # in case we are internal
+       fi
+
+       ###
+       # Cleaning tapes never go "ready", so instead we just sit here
+       # for "long enough" (as determined empirically by the user),
+       # then return success.
+       ###
+       if [ $loadslot -eq $cleanslot ]; then
+               Run sleep $cleancycle
+               Exit 0 "$loadslot" "$tape"
+               return $?                       # in case we are internal
+       fi
+
+       ###
+       # Wait for the drive to go online.
+       ###
+       waittime=0
+       ready=0
+       sleep $initial_poll_delay
+       while [ $waittime -lt $max_drive_wait ]; do
+               result=`Run $MT $MTF $tape rewind 2>&1`
+               if [ $? -eq 0 ]; then
+                       ready=1
+                       break
+               fi
+               sleep $poll_drive_ready
+               waittime=`expr $waittime + $poll_drive_ready`
+       done
+       if [ $ready -eq 0 ]; then
+               Exit 2 "$loadslot" "Drive not ready after" \
+                                  "$max_drive_wait seconds," \
+                                  "rewind said \"$result\""
+               return $?                       # in case we are internal
+       fi
+
+       if [ $loadslot -ne $cleanslot ]; then
+               rm -f $slotfile
+               echo $loadslot > $slotfile
+       fi
+       Exit 0 "$loadslot" "$tape"
+       return $?                               # in case we are internal
+}
+
+###
+# Return information about how the changer is configured and the current
+# state of the robot.
+###
+
+info() {
+       test -n "$DEBUG" && set -x
+       get_loaded_info
+       get_slot_list
+       Log       "INFO     -> first slot: $firstslot"
+       LogAppend "         -> current slot: $currentslot"
+       LogAppend "         -> loaded slot: $loadedslot"
+       LogAppend "         -> last slot: $lastslot"
+       LogAppend "         -> slot list: $slot_list"
+       LogAppend "         -> can go backwards: 1"
+       LogAppend "         -> havereader: $havereader"
+
+        ###
+       # Check if a barcode reader is configured or not.  If so, it
+       # passes the 4th item in the echo back to amtape signifying it
+       # can search based on barcodes.
+       ###
+       reader=
+        if [ $havereader -eq 1 ]; then
+               reader=1
+        fi
+
+       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=$#
+       Exit 0 "$currentslot" "$numslots 1 $reader"
+       return $?                               # in case we are internal
+}
+
+###
+# Read the labelfile and scan for a particular entry.
+###
+
+read_labelfile() {
+       labelfile_entry_found=0
+       labelfile_label=
+       labelfile_barcode=
+
+       lbl_search=$1
+       bc_search=$2
+
+       line=0
+       while read lbl bc junk; do
+               line=`expr $line + 1`
+               if [ -z "$lbl" -o -z "$bc" -o -n "$junk" ]; then
+                       Log       "ERROR    -> Line $line malformed: $lbl $bc $junk"
+                       LogAppend "         -> Remove $labelfile" \
+                                              "and run" \
+                                              "\"$sbindir/amtape $config update\""
+                       Exit 2 \
+                            "<none>" \
+                            "Line $line malformed in $labelfile: $lbl $bc $junk"
+                       return $?               # in case we are internal
+               fi
+               if [ $lbl = "$lbl_search" -o $bc = "$bc_search" ]; then
+                       if [ $labelfile_entry_found -ne 0 ]; then
+                               Log       "ERROR    -> Duplicate entries: $labelfile line $line"
+                               LogAppend "         -> Remove $labelfile" \
+                                                      "and run" \
+                                                      "\"$sbindir/amtape $config update\""
+                               Exit 2 \
+                                    "<none>" \
+                                    "Duplicate entries: $labelfile line $line"
+                               return $?       # in case we are internal
+                       fi
+                       labelfile_entry_found=1
+                       labelfile_label=$lbl
+                       labelfile_barcode=$bc
+               fi
+       done
+}
+
+###
+# Adds the label and barcode for the currently loaded tape to the
+# barcode file.  Return an error if the database is messed up.
+###
+
+addlabel() {
+       test -n "$DEBUG" && set -x
+       if [ $# -lt 1 ]; then
+               Exit 2 "<none>" "Missing -label argument"
+               return $?                       # in case we are internal
+       fi
+        tapelabel=$1
+       if [ $havereader -eq 0 ]; then
+               Exit 2 "<none>" "Not configured with barcode reader"
+               return $?                       # in case we are internal
+       fi
+        get_loaded_info
+       if [ $loadedslot -lt 0 ]; then
+               Exit 1 "<none>" "No tape currently loaded"
+               return $?                       # in case we are internal
+       fi
+       Log       "LABEL    -> Adding label \"$tapelabel\"" \
+                              "with barcode \"$loadedbarcode\"" \
+                              "for slot $loadedslot" \
+                              "into $labelfile"
+       read_labelfile "$tapelabel" "$loadedbarcode" < $labelfile
+       if [ $labelfile_entry_found -ne 0 ]; then
+               lf_val=
+               if [ "$labelfile_barcode" != "$loadedbarcode" ]; then
+                       lf_type=label
+                       lf_val=$tapelabel
+                       val_type=barcode
+                       old_val=$labelfile_barcode
+                       new_val=$loadedbarcode
+               elif [ "$labelfile_label" != "$tapelabel" ]; then
+                       lf_type=barcode
+                       lf_val=$loadedbarcode
+                       val_type=label
+                       old_val=$labelfile_label
+                       new_val=$tapelabel
+               fi
+               if [ -n "$lf_val" ]; then
+                       LogAppend "ERROR    -> !!! Label database corrupted !!!"
+                       LogAppend "         -> \"$old_val\" conflicts with" \
+                                              "new $val_type \"$new_val\"" \
+                                              "for $lf_type \"$lf_val\""
+                       LogAppend "         -> Remove $labelfile" \
+                                              "and run" \
+                                              "\"$sbindir/amtape $config update\""
+                       Exit 2 \
+                            "<none>" \
+                            "$tapelabel: \"$old_val\" conflicts with" \
+                            "new $val_type \"$new_val\"" \
+                            "for $lf_type \"$lf_val\""
+                       return $?               # in case we are internal
+               fi
+               LogAppend "         -> already synced"
+       else
+               echo "$tapelabel $loadedbarcode" >> $labelfile
+               LogAppend "         -> appended $labelfile entry:" \
+                                      "$tapelabel $loadedbarcode"
+       fi
+       Exit 0 "$loadedslot" "$tape"
+       return $?                               # in case we are internal
+}
+
+###
+# Look for a label in the barcode file.  If found, locate the slot it's
+# in by looking for the barcode in the mtx output, then load that tape.
+###
+
+searchtape() {
+       test -n "$DEBUG" && set -x
+       if [ $# -lt 1 ]; then
+               Exit 2 "<none>" "Missing -search argument"
+               return $?                       # in case we are internal
+       fi
+        tapelabel=$1
+       if [ $havereader -eq 0 ]; then
+               Exit 2 "<none>" "Not configured with barcode reader"
+               return $?                       # in case we are internal
+       fi
+       Log "SEARCH   -> Hunting for label \"$tapelabel\""
+       read_labelfile "$tapelabel" "" < $labelfile
+       if [ $labelfile_entry_found -eq 0 ]; then
+               LogAppend "         -> !!! label \"$tapelabel\" not found" \
+                                      "in $labelfile !!!"
+               LogAppend "         -> Remove $labelfile" \
+                                      "and run" \
+                                      "\"$sbindir/amtape $config update\""
+               Exit 2 \
+                    "<none>" \
+                    "$tapelabel: label \"$tapelabel\" not found in $labelfile"
+               return $?                       # in case we are internal
+       fi
+       LogAppend "         -> barcode is \"$labelfile_barcode\""
+       get_mtx_status
+       foundslot=`sed -n '
+/VolumeTag *= *'$labelfile_barcode' *$/                        {
+       s/.*Storage Element \([0-9][0-9]*\).*/\1/p
+       q
+}
+' < $mtx_status`
+       LogAppend "         -> foundslot is $foundslot"
+       if [ -z "$foundslot" ]; then
+               LogAppend "ERROR    -> !!! Could not find slot" \
+                                      "for barcode \"$labelfile_barcode\"!!!"
+               LogAppend "         -> Remove $labelfile" \
+                                      "and run" \
+                                      "\"$sbindir/amtape $config update\""
+               Exit 2 \
+                    "<none>" \
+                    "barcode \"$labelfile_barcode\"" \
+                    "not found in mtx status output"
+               return $?                       # in case we are internal
+       fi
+       # Call loadslot without doing it as an internal and let it finish
+       # things up.
+       loadslot $foundslot
+       # NOTREACHED
+       Exit 2 "<none>" "searchtape: should not get here"
+       return $?                               # in case we are internal
+}
+
+###
+# Program invocation begins here
+###
+
+if [ $# -lt 1 ]; then
+       Exit 2 "<none>" "Usage: $myname -command args"
+fi
+cmd=$1
+shift
+case "$cmd" in
+-slot)
+       loadslot "$@"
+       ;;
+-info)
+       info "$@"
+       ;;
+-reset)
+       reset "$@"
+       ;;
+-eject)
+       eject "$@"
+       ;;
+-label) 
+       addlabel "$@"
+       ;;
+-search)
+       searchtape "$@"
+       ;;
+-clean)
+       loadslot clean
+       ;;
+*)
+       Exit 2 "<none>" "unknown option: $cmd"
+       ;;
+esac
+
+Exit 2 "<none>" "$myname: should not get here"
diff --git a/changer-src/libscsi.h b/changer-src/libscsi.h
new file mode 100644 (file)
index 0000000..2f8dfea
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *     $Id: libscsi.h,v 1.4.4.4.4.1 2001/07/10 22:03:14 jrjackson Exp $
+ *
+ *     libscsi.h -- library header for routines to handle the changer
+ *                     support for chio based systems
+ *
+ *     Author: Eric Schnoebelen, eric@cirr.com
+ *     based on work by: Larry Pyeatt,  pyeatt@cs.colostate.edu 
+ *     Copyright: 1997, Eric Schnoebelen
+ *             
+ *      Michael C. Povel 03.06.98 added function eject_tape
+ */
+
+#ifndef LIBSCSI_H
+#define LIBSCSI_H
+
+#include "amanda.h"
+
+/*
+ * This function gets the actual cleaning state of the drive 
+ */
+int get_clean_state P((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));
+
+/*
+ * Eject the actual tape from the tapedrive
+ */
+void eject_tape P((char *tape, int type));
+
+
+/* 
+ * is the specified slot empty?
+ */
+int isempty P((int fd, int slot));
+
+/*
+ * find the first empty slot 
+ */
+int find_empty P((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));
+
+
+/*
+ * unloads the drive, putting the tape in the specified slot 
+ */
+int unload P((int fd, int drive, int slot));
+
+/*
+ * moves tape from the specified slot into the drive 
+ */
+int load P((int fd, int drive, int slot));
+
+/* 
+ * return the number of slots in the robot
+ */
+int get_slot_count P((int fd));
+
+/*
+ * return the number of drives in the robot
+ */
+int get_drive_count P((int fd));
+
+#endif /* !LIBSCSI_H */
diff --git a/changer-src/scsi-aix.c b/changer-src/scsi-aix.c
new file mode 100644 (file)
index 0000000..7e00fda
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * 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: scsi-aix.c,v 1.1.2.14.4.3.2.3 2003/01/26 19:20:56 martinea Exp $
+ *
+ * Interface to execute SCSI commands on an AIX System
+ *
+ * Copyright (c) Thomas Hepper th@ant.han.de
+ */
+
+
+#include <amanda.h>
+
+#ifdef HAVE_AIX_LIKE_SCSI
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <sys/scarray.h>
+#include <sys/tape.h>
+
+#include <scsi-defs.h>
+#include <gscdds.h>
+
+void SCSI_OS_Version()
+{
+#ifndef lint
+   static char rcsid[] = "$Id: scsi-aix.c,v 1.1.2.14.4.3.2.3 2003/01/26 19:20:56 martinea Exp $";
+   DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
+#endif
+}
+
+
+int SCSI_OpenDevice(int ip)
+{
+  int DeviceFD;
+  int i;
+  extern OpenFiles_T *pDev;
+  
+  if (pDev[ip].inqdone == 0)
+    {
+      pDev[ip].inqdone = 1;
+      /*
+       * Check if it is an gsc (generic SCSI device)
+       */
+      if (strncmp("/dev/gsc", pDev[ip].dev, 8) == 0)
+        {
+         pDev[ip].flags = AIX_USE_GSC;
+          DeviceFD = open(pDev[ip].dev, 0);
+        } else {
+          DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC);
+        }
+      if (DeviceFD > 0)
+       {
+         pDev[ip].avail = 1;
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].SCSI = 0;
+          pDev[ip].devopen = 1;
+          pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
+
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+           {
+             if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
+               {
+                 for (i=0;i < 16;i++)
+                   pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+                 for (i=15; i >= 0 && !isalnum(pDev[ip].ident[i]) ; i--)
+                   {
+                     pDev[ip].ident[i] = '\0';
+                   }
+                 pDev[ip].SCSI = 1;
+
+                 if (pDev[ip].inquiry->type == TYPE_TAPE)
+                 {
+                         pDev[ip].type = stralloc("tape");
+                 }
+
+                 if (pDev[ip].inquiry->type == TYPE_CHANGER)
+                 {
+                         pDev[ip].type = stralloc("changer");
+                 }
+
+                 PrintInquiry(pDev[ip].inquiry);
+                 return(1); 
+               } else {
+                 close(DeviceFD);
+                 free(pDev[ip].inquiry);
+                 return(0);
+               }
+           } else {
+             free(pDev[ip].inquiry);
+             pDev[ip].inquiry = NULL;
+             return(1);
+           }
+        return(1);
+       } else {
+        dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
+         return(0);
+       }
+    } else {
+      if ((DeviceFD = openx(pDev[ip].dev, O_RDWR, 0, SC_DIAGNOSTIC)) > 0)
+        {
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].devopen = 1;
+          return(1);
+        }
+    }
+  return(0);
+}
+
+int SCSI_CloseDevice(int DeviceFD)
+{
+  int ret;
+  extern OpenFiles_T *pDev;
+
+  ret = close(pDev[DeviceFD].fd);
+  pDev[DeviceFD].devopen = 0;
+  return(ret);
+
+}
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *RequestSenseBuf,
+                        int RequestSenseLength)
+{
+  extern OpenFiles_T *pDev;
+  extern FILE * debug_file;
+  CDB_T CDBSENSE;
+  CDB_T SINQ;
+  ExtendedRequestSense_T ExtendedRequestSense;
+  struct sc_iocmd ds;
+  scmd_t scmd;
+  char sbyte;
+  int Result;
+  int isbusy = 0;
+  int target = 3;
+
+
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(SCSI_ERROR);
+    }
+
+
+  if (pDev[DeviceFD].flags == AIX_USE_GSC)
+    {
+      scmd.cdb = CDB;
+      scmd.cdblen = CDB_Length;
+      scmd.data_buf = DataBuffer;
+      scmd.datalen = DataBufferLength;
+      scmd.sense_buf = RequestSenseBuf;
+      scmd.senselen = RequestSenseLength;
+      scmd.statusp = &sbyte;
+      scmd.timeval = 60;
+      switch (Direction) 
+        {
+        case Input:
+          scmd.rw = 0;
+          break;
+        case Output:
+          scmd.rw = 1;
+          break;
+        }
+
+      if (ioctl(pDev[DeviceFD].fd, GSC_CMD, (caddr_t) &scmd) < 0) {
+        return(SCSI_ERROR);
+      }
+      return(SCSI_OK);
+
+    } else {
+      bzero(&ds, sizeof(struct sc_iocmd));
+      bzero(RequestSenseBuf, RequestSenseLength);
+      bzero(&ExtendedRequestSense, sizeof(ExtendedRequestSense_T));
+      
+      ds.flags = SC_ASYNC; 
+      /* Timeout */
+      ds.timeout_value = 60;
+      bcopy(CDB, ds.scsi_cdb, CDB_Length);
+      ds.command_length = CDB_Length;
+      /* 
+       *  Data buffer for results 
+       * If the size of the buffer is 0
+       * then keep this fields untouched           
+       */
+      if (DataBufferLength > 0)
+        {
+          ds.buffer = DataBuffer;
+          ds.data_length = DataBufferLength;
+        }
+      
+      /* Sense Buffer is not available on AIX ?*/
+      /*
+        ds.req_sense_length = 255;
+        ds.request_sense_ptr = (char *)RequestSense;
+      */
+      switch (Direction) 
+        {
+        case Input:
+          ds.flags = ds.flags | B_READ;
+          break;
+        case Output:
+          ds.flags = ds.flags | B_WRITE;
+          break;
+        }
+      DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
+      
+      if (pDev[DeviceFD].devopen == 0)
+        SCSI_OpenDevice(DeviceFD);
+      Result = ioctl(pDev[DeviceFD].fd, STIOCMD, &ds);
+      SCSI_CloseDevice(DeviceFD);
+      
+      if ( Result < 0)
+        {
+          switch (ds.scsi_bus_status)
+            {
+            case SC_GOOD_STATUS:
+              SINQ[0] = SC_COM_REQUEST_SENSE;
+              SINQ[1] = 0; 
+              SINQ[2] = 0;
+              SINQ[3] = 0;
+              SINQ[4] = 0x1D;
+              SINQ[5] = 0x80;
+              bcopy(SINQ, ds.scsi_cdb, 6);
+              ds.command_length = 6;
+              ds.buffer = RequestSenseBuf;
+              ds.data_length = RequestSenseLength;
+              
+              if (pDev[DeviceFD].devopen == 0)
+                SCSI_OpenDevice(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; 
+              SINQ[2] = 0;
+              SINQ[3] = 0;
+              SINQ[4] = 0x1D;
+              SINQ[5] = 0x80;
+              bcopy(SINQ, ds.scsi_cdb, 6);
+              ds.command_length = 6;
+              ds.buffer = RequestSenseBuf;
+              ds.data_length = RequestSenseLength;
+
+              if (pDev[DeviceFD].devopen == 0)
+                SCSI_OpenDevice(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
+               *
+               RequestSense(DeviceFD, &ExtendedRequestSense, 0);
+               DecodeExtSense(&ExtendedRequestSense, "SCSI_ExecuteCommand:", debug_file);
+               bcopy(&ExtendedRequestSense, RequestSenseBuf, RequestSenseLength);
+              */
+              dbprintf(("ioctl on %d return %d\n", pDev[DeviceFD].fd, Result));
+              dbprintf(("ret: %d errno: %d (%s)\n", Result, errno, ""));
+              dbprintf(("data_length:     %d\n", ds.data_length));
+              dbprintf(("buffer:          0x%X\n", ds.buffer));
+              dbprintf(("timeout_value:   %d\n", ds.timeout_value));
+              dbprintf(("status_validity: %d\n", ds.status_validity));
+              dbprintf(("scsi_bus_status: 0x%X\n", ds.scsi_bus_status));
+              dbprintf(("adapter_status:  0x%X\n", ds.adapter_status));
+              dbprintf(("adap_q_status:   0x%X\n", ds.adap_q_status));
+              dbprintf(("q_tag_msg:       0x%X\n", ds.q_tag_msg));
+              dbprintf(("flags:           0X%X\n", ds.flags));
+              return(SCSI_ERROR);
+            }
+        }
+      return(SCSI_OK);
+    }
+}
+
+int SCSI_Scan()
+{
+  int fd;
+  extern int errno;
+  struct sc_inquiry si;
+  u_char buf[255];
+  int target;
+  int lun;
+  int isbusy;
+  char type;
+  char bus[] = "/dev/scsi0";
+  
+  if ((fd = open(bus, O_RDWR)) == -1)
+    return(1);
+
+  for (target = 0; target < 7; target++) 
+    {
+      for (lun = 0; lun < 7; lun++)
+        {
+          printf("Target:Lun %d:%d\n", target,lun);
+          if (ioctl(fd, SCIOSTART, IDLUN(target, lun)) == -1) {
+            if (errno == EINVAL) {
+              printf("is in use\n");
+              isbusy = 1;
+            } else {
+              return(1);
+            }
+          } else {
+            isbusy = 0;
+          }
+          
+          bzero(&si, sizeof(si));
+          si.scsi_id = target;
+          si.lun_id = lun;
+          si.inquiry_len = 255;
+          si.inquiry_ptr = (char *)&buf;
+          if (ioctl(fd, SCIOINQU, &si) == -1)
+            {
+              printf("SCIOINQU: %s\n", strerror(errno));
+            } else {
+              dump_hex(&buf, 255, DEBUG_INFO, SECTION_SCSI);
+              type = buf[0] & 0x1f;
+              buf[8+28] = 0;
+              printf(stdout,"%-28s|Device Type %d\n",buf[8], type);
+            }
+          if (!isbusy && ioctl(fd, SCIOSTOP, IDLUN(target, lun)) == -1)
+            return(1);
+        }
+    }
+}
+
+int Tape_Ioctl(int DeviceFD, int command)
+{
+  extern OpenFiles_T *pDev;
+  int ret = -1;
+  return(ret);
+}
+
+int Tape_Status( int DeviceFD)
+{
+/*
+  Not yet
+*/
+  return(-1);
+}
+
+int ScanBus(int print)
+{
+/*
+  Not yet
+*/
+  SCSI_Scan();
+  return(-1);
+}
+
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-bsd.c b/changer-src/scsi-bsd.c
new file mode 100644 (file)
index 0000000..a152b24
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * 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: scsi-bsd.c,v 1.1.2.10.4.2.2.4 2003/06/05 20:44:23 martinea Exp $
+ *
+ * Interface to execute SCSI commands on an BSD System (FreeBSD)
+ *
+ * Copyright (c) Thomes Hepper th@ant.han.de
+ */
+
+
+#include <amanda.h>
+
+#ifdef HAVE_BSD_LIKE_SCSI
+
+/*
+#ifdef HAVE_STDIO_H
+*/
+#include <stdio.h>
+/*
+#endif
+*/
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <sys/scsiio.h>
+#include <sys/mtio.h>
+
+#include <scsi-defs.h>
+
+void SCSI_OS_Version()
+{
+#ifndef lint
+   static char rcsid[] = "$Id: scsi-bsd.c,v 1.1.2.10.4.2.2.4 2003/06/05 20:44:23 martinea Exp $";
+   DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
+#endif
+}
+
+
+/*
+ * Check if the device is already open,
+ * if no open it and save it in the list 
+ * of open files.
+ * 
+ * Return:
+ * 0  -> device not opened
+ * 1  -> sucess , device open
+ * -1 -> fatal error
+ */
+int SCSI_OpenDevice(int ip)
+{
+  extern OpenFiles_T *pDev;
+  int i;
+  char * DeviceName;
+
+
+  /*
+   * If the SCSI inquiry was not done lets try to get
+   * some infos about the device
+   */
+  if (pDev[ip].inqdone == 0) {
+    pDev[ip].inqdone = 1;                                                     /* Set it to 1, so the inq is done */
+    pDev[ip].SCSI = 0;                                                        /* This will only be set if the inquiry works */
+    pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
+    
+    if (( pDev[ip].fd = open(pDev[ip].dev, O_RDWR)) > 0)                      /* We need the device in read/write mode */
+      {
+        pDev[ip].devopen = 1;                                                 /* The device is open for use */
+        pDev[ip].avail = 1;                                                   /* And it is available, it could be opened */
+        if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)            /* Lets try to get the result of an SCSI inquiry */
+          {
+            if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)  /* If it worked and we got an type of */
+                                                                                                /* either tape or changer continue */
+              {
+                for (i=0;i < 16 ;i++)                                         /* Copy the product ident to the pDev struct */
+                  pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+                for (i=15; i >= 0 && !isalnum(pDev[ip].ident[i]); i--)        /* And terminate it with an \0, remove all white space */
+                  {
+                    pDev[ip].ident[i] = '\0';
+                  }
+                pDev[ip].SCSI = 1;                                            /* OK, its an SCSI device ... */
+
+                 if (pDev[ip].inquiry->type == TYPE_TAPE)
+                 {
+                         pDev[ip].type = stralloc("tape");
+                 }
+
+                 if (pDev[ip].inquiry->type == TYPE_CHANGER)
+                 {
+                         pDev[ip].type = stralloc("changer");
+                 }
+
+                PrintInquiry(pDev[ip].inquiry);                               /* Some debug output */
+                return(1);                                                    /* All done */
+              } else {
+                free(pDev[ip].inquiry);                                       /* The SCSI was ok, but not an TAPE/CHANGER device ... */
+                pDev[ip].devopen = 0;
+                pDev[ip].avail = 0;
+                close(pDev[ip].fd); 
+                return(0);                                                    /*Might be an ChgExit is better */
+              }
+          } else { /* if SCSI_Inquiry */                                      /* The inquiry failed */
+            free(pDev[ip].inquiry);                                           /* free the allocated memory */
+            pDev[ip].inquiry = NULL;
+            return(1);                                                        /* Its not an SCSI device, but can be used for read/write */
+          }
+      }  /* open() */
+    return(0);                                                                /* Open failed .... */
+  } else { /* pDev[ip].inqdone */                                             /* OK this is the way we go if the device */
+    if (( pDev[ip].fd = open(pDev[ip].dev, O_RDWR)) > 0)                      /* was opened successfull before */
+      {
+        pDev[ip].devopen = 1;
+        return(1);
+      } 
+  }
+  return(0);                                                                 /* Default, return device not available */
+}
+
+/*
+ * Close the device 
+ * abd set the flags in the device struct 
+ *
+ */
+int SCSI_CloseDevice(int DeviceFD)
+{
+  int ret;
+  extern OpenFiles_T *pDev;
+  
+  ret = close(pDev[DeviceFD].fd) ;
+  pDev[DeviceFD].devopen = 0;
+  return(ret);
+}
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *pRequestSense,
+                        int RequestSenseLength)
+{
+  extern OpenFiles_T *pDev;
+  ExtendedRequestSense_T ExtendedRequestSense;
+  scsireq_t ds;
+  int Zero = 0, Result;
+  int retries = 5;
+  extern int errno;
+  
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(SCSI_ERROR);
+    }
+
+  memset(&ds, 0, sizeof(scsireq_t));
+  memset(pRequestSense, 0, RequestSenseLength);
+  memset(&ExtendedRequestSense, 0 , sizeof(ExtendedRequestSense_T)); 
+  
+  ds.flags = SCCMD_ESCAPE; 
+  /* Timeout */
+  ds.timeout = 120000;
+  /* Set the cmd */
+  memcpy(ds.cmd, CDB, CDB_Length);
+  ds.cmdlen = CDB_Length;
+  /* Data buffer for results */
+  if (DataBufferLength > 0)
+    {
+      ds.databuf = (caddr_t)DataBuffer;
+      ds.datalen = DataBufferLength;
+    }
+  /* Sense Buffer */
+  /*
+    ds.sense = (u_char)pRequestSense;
+  */
+  ds.senselen = RequestSenseLength;
+    
+  switch (Direction) 
+    {
+    case Input:
+      ds.flags = ds.flags | SCCMD_READ;
+      break;
+    case Output:
+      ds.flags = ds.flags | SCCMD_WRITE;
+      break;
+    }
+    
+  while (--retries > 0) {
+    
+    if (pDev[DeviceFD].devopen == 0)
+      {
+        SCSI_OpenDevice(DeviceFD);
+      }
+    Result = ioctl(pDev[DeviceFD].fd, SCIOCCOMMAND, &ds);
+    SCSI_CloseDevice(DeviceFD);
+   
+    memcpy(pRequestSense, ds.sense, RequestSenseLength);
+    if (Result < 0)
+      {
+        dbprintf(("errno : %d\n",errno));
+        return (SCSI_ERROR);
+      }
+    dbprintf(("SCSI_ExecuteCommand(BSD) %02X STATUS(%02X) \n", CDB[0], ds.retsts));
+    switch (ds.retsts)
+      {
+      case SCCMD_BUSY:                /*  BUSY */
+        break;
+      case SCCMD_OK:                /*  GOOD */
+        return(SCSI_OK);
+        break;
+      case SCCMD_SENSE:               /*  CHECK CONDITION */
+        return(SCSI_SENSE);
+        break;
+      default:
+        continue;
+      }
+  }   
+  return(SCSI_SENSE);
+}
+
+/*
+ * Send the command to the device with the
+ * ioctl interface
+ */
+int Tape_Ioctl( int DeviceFD, int command)
+{
+  extern OpenFiles_T *pDev;
+  struct mtop mtop;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  switch (command)
+    {
+    case IOCTL_EJECT:
+      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));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
+
+  SCSI_CloseDevice(DeviceFD);
+  return(ret);  
+}
+
+int Tape_Status( int DeviceFD)
+{
+/* 
+  Not yet
+*/
+  return(-1);
+}
+
+int ScanBus(int print)
+{
+/*
+  Not yet
+*/
+  return(-1);
+}
+
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-cam.c b/changer-src/scsi-cam.c
new file mode 100644 (file)
index 0000000..d4a2eb0
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * 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: scsi-cam.c,v 1.10.4.1.2.4 2004/04/29 20:47:40 martinea Exp $
+ *
+ * Interface to execute SCSI commands on an system with cam support
+ * Current support is for FreeBSD 4.x
+ *
+ * Copyright (c) Thomes Hepper th@ant.han.de
+ */
+
+
+#include <amanda.h>
+
+#ifdef HAVE_CAM_LIKE_SCSI
+
+/*
+#ifdef HAVE_STDIO_H
+*/
+#include <stdio.h>
+/*
+#endif
+*/
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_CAMLIB_H
+# include <camlib.h>
+#endif
+
+#include <cam/scsi/scsi_message.h>
+
+#ifdef HAVE_SYS_MTIO_H
+#include <sys/mtio.h>
+#endif
+
+#include <scsi-defs.h>
+
+extern OpenFiles_T *pChangerDev;
+extern OpenFiles_T *pTapeDev;
+extern OpenFiles_T *pTapeDevCtl;
+extern FILE *debug_file;
+
+
+void SCSI_OS_Version()
+{
+#ifndef lint
+   static char rcsid[] = "$Id: scsi-cam.c,v 1.10.4.1.2.4 2004/04/29 20:47:40 martinea Exp $";
+   DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
+#endif
+}
+
+/* parse string of format 1:2:3 and fill in path, target, lun
+   returns 0  if it doesn't look like btl
+   returns 1  if parse successful
+   calls ChgExit if it looks like btl but formatted improperly
+*/
+
+int parse_btl(char *DeviceName, 
+          path_id_t *path, target_id_t *target, lun_id_t *lun) 
+{
+  char *p;
+  if (strstr(DeviceName, ":") == NULL) 
+    return 0;
+
+  p = strtok(DeviceName, ":");
+  sscanf(p,"%d", path);
+          
+  if ((p = strtok(NULL,":")) == NULL) {
+      free(DeviceName);
+      ChgExit("SCSI_OpenDevice", "target in Device Name not found", FATAL);
+  }
+  sscanf(p,"%d", target);
+  if ((p = strtok(NULL,":")) == NULL) {
+      free(DeviceName);
+      ChgExit("SCSI_OpenDevice", "lun in Device Name not found", FATAL);
+  }
+  sscanf(p,"%d", lun);
+  return 1;
+}
+
+/*
+ * Check if the device is already open,
+ * if no open it and save it in the list 
+ * of open files.
+ * DeviceName can be an device name, /dev/nrsa0 for example
+ * or an bus:target:lun path, 0:4:0 for bus 0 target 4 lun 0
+ */
+
+int SCSI_OpenDevice(int ip)
+{
+  extern OpenFiles_T *pDev;
+  char *DeviceName;
+  int DeviceFD;
+  int i;
+  path_id_t path;
+  target_id_t target;
+  lun_id_t lun;
+
+  DeviceName = stralloc(pDev[ip].dev);
+
+  if (pDev[ip].inqdone == 0) {
+    pDev[ip].inqdone = 1;
+    pDev[ip].SCSI = 0;
+    pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
+    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].avail = 1;
+      pDev[ip].SCSI = 1;
+      pDev[ip].devopen = 1;
+      if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0) {
+        if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER) {
+          for (i=0;i < 16;i++)
+            pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+
+          for (i=15; i >= 0 && !isalnum(pDev[ip].ident[i]); i--) {
+            pDev[ip].ident[i] = '\0';
+          }
+          pDev[ip].SCSI = 1;
+
+         if (pDev[ip].inquiry->type == TYPE_TAPE)
+         {
+                 pDev[ip].type = stralloc("tape");
+         }
+
+         if (pDev[ip].inquiry->type == TYPE_CHANGER)
+         {
+                 pDev[ip].type = stralloc("changer");
+         }
+
+          PrintInquiry(pDev[ip].inquiry);
+          return(1);
+        } else {
+          free(pDev[ip].inquiry);
+          return(0);
+        }
+      } else {
+        pDev[ip].SCSI = 0;
+        free(pDev[ip].inquiry);
+        pDev[ip].inquiry = NULL;
+        return(1);
+      }
+    } else { /* Device open failed */
+      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); 
+}
+
+int SCSI_CloseDevice(int DeviceFD)
+{
+  int ret;
+  extern OpenFiles_T *pDev;
+
+  if (pDev[DeviceFD].SCSI == 1)
+    {
+      cam_close_device(pDev[DeviceFD].curdev);
+      pDev[DeviceFD].devopen = 0;
+    } else {
+      close(pDev[DeviceFD].fd);
+    }
+  return(0);
+}
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *pRequestSense,
+                        int RequestSenseLength)
+{
+  ExtendedRequestSense_T ExtendedRequestSense;
+  extern OpenFiles_T *pDev;
+  union ccb *ccb;
+  int ret;
+  uint32_t ccb_flags;
+  OpenFiles_T *pwork = NULL;
+
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(SCSI_ERROR);
+    }
+
+  /* 
+   * CLear the SENSE buffer
+   */
+  bzero(pRequestSense, RequestSenseLength);
+
+  DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
+
+  ccb = cam_getccb(pDev[DeviceFD].curdev);
+
+  /* Build the CCB */
+  bzero(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio));
+  bcopy(&CDB[0], &ccb->csio.cdb_io.cdb_bytes, CDB_Length);
+
+  switch (Direction)
+    {
+    case Input:
+      if (DataBufferLength == 0)
+        {
+          ccb_flags = CAM_DIR_NONE;
+        } else {
+          ccb_flags = CAM_DIR_IN;
+        }
+      break;
+    case Output:
+      if (DataBufferLength == 0)
+        {
+          ccb_flags = CAM_DIR_NONE;
+        } else {     
+          ccb_flags = CAM_DIR_OUT;
+        }
+      break;
+    default:
+      ccb_flags = CAM_DIR_NONE;
+      break;
+    }
+  
+  cam_fill_csio(&ccb->csio,
+                /* retires */ 1,
+                /* cbfncp */ NULL,
+                /* flags */ ccb_flags,
+                /* tag_action */ MSG_SIMPLE_Q_TAG,
+                /* data_ptr */ (u_int8_t*)DataBuffer,
+                /* dxfer_len */ DataBufferLength,
+                /* sense_len */ SSD_FULL_SIZE,
+                /* cdb_len */ CDB_Length,
+                /* timeout */ 600 * 1000);
+  
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+  
+  ret = cam_send_ccb(pDev[DeviceFD].curdev, ccb);
+  SCSI_CloseDevice(DeviceFD);
+
+  if ( ret == -1)
+    {
+      cam_freeccb(ccb);
+      return(SCSI_ERROR);
+    }
+  
+  /* 
+   * copy the SENSE data to the Sense Buffer !!
+   */
+  memcpy(pRequestSense, &ccb->csio.sense_data, RequestSenseLength);
+  
+  /* ToDo add error handling */
+  if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+    {
+      dbprintf(("SCSI_ExecuteCommand return %d\n", (ccb->ccb_h.status & CAM_STATUS_MASK)));
+      return(SCSI_ERROR);
+    }
+
+  cam_freeccb(ccb);
+  return(SCSI_OK);
+}
+
+/*
+ * Send the command to the device with the
+ * ioctl interface
+ */
+int Tape_Ioctl( int DeviceFD, int command)
+{
+  extern OpenFiles_T *pDev;
+  struct mtop mtop;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  switch (command)
+    {
+    case IOCTL_EJECT:
+      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));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
+
+  SCSI_CloseDevice(DeviceFD);
+  return(ret);  
+}
+
+int Tape_Status( int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  struct mtget mtget;
+  int ret = 0;
+  
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
+  {
+     dbprintf(("Tape_Status error ioctl %d\n",errno));
+     SCSI_CloseDevice(DeviceFD);
+     return(-1);
+  }
+
+  dbprintf(("ioctl -> mtget.mt_dsreg %lX\n",mtget.mt_dsreg));
+  dbprintf(("ioctl -> mtget.mt_erreg %lX\n",mtget.mt_erreg));
+
+  /*
+   * I have no idea what is the meaning of the bits in mt_erreg
+   * I assume that nothing set is tape loaded
+   * 0x2 is no tape online
+   */
+  if (mtget.mt_erreg == 0)
+    {
+      ret = ret | TAPE_ONLINE;
+    }
+
+  if (mtget.mt_erreg & 0x2)
+    {
+      ret = ret | TAPE_NOT_LOADED;
+    }
+  
+  SCSI_CloseDevice(DeviceFD);
+  return(ret);
+}
+
+/*
+ * Scans the bus for device with the type 'tape' or 'robot'
+ *
+ */
+int ScanBus(int print)
+{
+  int bus,target,lun;
+  int count = 0;
+  extern OpenFiles_T *pDev;
+  
+  for (bus = 0;bus < 3; bus++)
+    {
+      pDev[count].dev = malloc(10);
+      for (target = 0;target < 8; target++)
+        {
+          for (lun = 0; lun < 8; lun++)
+            {
+              sprintf(pDev[count].dev, "%d:%d:%d", bus, target, lun);
+              pDev[count].inqdone = 0;
+              if (OpenDevice(count, pDev[count].dev, "Scan", NULL))
+                {
+                  if (pDev[count].inquiry->type == TYPE_TAPE ||
+                      pDev[count].inquiry->type == TYPE_CHANGER)
+                    {
+                      count++;
+                      pDev[count].dev = malloc(10);
+                    } else {
+                      if (print)
+                        {
+                          printf("bus:target:lun -> %s == ",pDev[count].dev);
+                          
+                          switch (pDev[count].inquiry->type)
+                            {
+                            case TYPE_DISK:
+                              printf("Disk");
+                              break;
+                            case TYPE_TAPE:
+                              printf("Tape");
+                              break;
+                            case TYPE_PRINTER:
+                              printf("Printer");
+                              break;
+                            case TYPE_PROCESSOR:
+                              printf("Processor");
+                              break;
+                            case TYPE_WORM:
+                              printf("Worm");
+                              break;
+                            case TYPE_CDROM:
+                              printf("Cdrom");
+                              break;
+                            case TYPE_SCANNER:
+                              printf("Scanner");
+                              break;
+                            case TYPE_OPTICAL:
+                              printf("Optical");
+                              break;
+                            case TYPE_CHANGER:
+                              printf("Changer");
+                              break;
+                            case TYPE_COMM:
+                              printf("Comm");
+                              break;
+                            default:
+                              printf("unknown %d",pDev[count].inquiry->type);
+                              break;
+                            }
+                          printf("\n");
+                        }
+                    } 
+                }
+            }
+        }
+    }
+}
+
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-changer-driver.c b/changer-src/scsi-changer-driver.c
new file mode 100644 (file)
index 0000000..2bc0507
--- /dev/null
@@ -0,0 +1,6202 @@
+ #ifndef lint
+static char rcsid[] = "$Id: scsi-changer-driver.c,v 1.1.2.27.2.7.2.10 2003/01/26 19:20:56 martinea Exp $";
+#endif
+/*
+ * Interface to control a tape robot/library connected to the SCSI bus
+ *
+ * Copyright (c) Thomas Hepper th@ant.han.de
+ */
+
+#include <amanda.h>
+
+#ifdef HAVE_DMALLOC_H
+#include <dmalloc.h>
+#endif
+
+#include "arglist.h"
+/*
+#ifdef HAVE_STDIO_H
+*/
+#include <stdio.h>
+/*
+#endif
+*/
+#ifdef  HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#
+#ifdef STDC_HEADERS
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+#include "scsi-defs.h"
+
+#include "tapeio.h"
+
+extern int TapeEject(int DeviceFD);
+
+extern FILE *debug_file;
+
+int PrintInquiry(SCSIInquiry_T *);
+int GenericElementStatus(int DeviceFD, int InitStatus);
+int SDXElementStatus(int DeviceFD, int InitStatus);
+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 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 SCSI_AlignElements(int DeviceFD, int MTE, int DTE, int STE);
+
+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 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();
+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 *);
+
+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);
+
+/*
+ * 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);
+
+int SCSI_Run(int DeviceFD,
+            Direction_T Direction,
+            CDB_T CDB,
+            int CDB_Length,
+            void *DataBuffer,
+            int DataBufferLength,
+            char *pRequestSense,
+            int 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_TestUnitReady(int, RequestSense_T *);
+int SCSI_ModeSense(int DeviceFD, 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);
+
+int SCSI_ReadElementStatus(int DeviceFD, 
+                           unsigned char type,
+                           unsigned char lun,
+                           unsigned char VolTag,
+                           int StartAddress,
+                           int NoOfElements,
+                          int DescriptorSize,
+                          char **data);
+
+FILE *StatFile;
+
+SC_COM_T SCSICommand[] = {
+  {0x00,
+   6,
+   "TEST UNIT READY"},
+  {0x01,
+   6,
+   "REWIND"},
+  {0x03,
+   6,
+   "REQUEST SENSE"},
+  {0x07,
+   6,
+   "INITIALIZE ELEMENT STATUS"},
+  {0x12,
+   6,
+   "INQUIRY"},
+  {0x13,
+   6,
+   "ERASE"},
+  {0x15,
+   6,
+   "MODE SELECT"},
+  {0x1A,
+   6,
+   "MODE SENSE"},
+  {0x1B,
+   6,
+   "UNLOAD"},
+  {0x4D,
+   10,
+   "LOG SENSE"}, 
+  {0xA5,
+   12,
+   "MOVE MEDIUM"},
+  { 0xE5,
+    12,
+   "VENDOR SPECIFIC"},
+  {0xB8,
+   12,
+   "READ ELEMENT STATUS"},
+  {0, 0, 0}
+};
+
+ChangerCMD_T ChangerIO[] = {
+  {"generic_changer",
+   "Generic driver changer [generic_changer]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  /* HP Devices */
+  {"C1553A",
+   "HP Auto Loader [C1553A]",
+   GenericMove,
+   GenericElementStatus,
+   DoNothing,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler}, 
+  /* Exabyte Devices */
+  {"EXB-10e",      
+   "Exabyte Robot [EXB-10e]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"EXB-120",   
+   "Exabyte Robot [EXB-120]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   EXB_BarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"EXB-210",   
+   "Exabyte Robot [EXB-210]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   EXB_BarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"EXB-85058HE-0000",        
+   "Exabyte Tape [EXB-85058HE-0000]",
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  /* Tandberg Devices */
+  {"TDS 1420",              
+   "Tandberg Robot (TDS 1420)",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+    /* ADIC Devices */
+  {"VLS DLT",               
+   "ADIC VLS DLT Library [VLS DLT]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"VLS SDX",               
+   "ADIC VLS DLT Library [VLS SDX]",
+   SDXMove,
+   SDXElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"FastStor DLT",               
+   "ADIC FastStor DLT Library [FastStor DLT]",
+   SDXMove,
+   DLT448ElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"Scalar DLT 448",
+   "ADIC DLT 448 [Scalar DLT 448]",
+   GenericMove,
+   DLT448ElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+   /* Sepctra Logic Devices */
+  {"215",
+   "Spectra Logic TreeFrog[215]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   TreeFrogBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  /* BreeceHill Q7 */
+  {"Quad 7",
+   "Breece Hill Quad 7",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  /* Quantum Devices */
+  {"L500",
+   "ATL [L500]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  /* 
+   * And now the tape devices
+   */
+  /* The generic handler if nothing matches */
+  {"generic_tape",
+   "Generic driver tape [generic_tape]",
+   GenericMove,
+   GenericElementStatus,
+   GenericResetStatus,
+   GenericFree,
+   GenericEject,
+   GenericClean,
+   GenericRewind,
+   NoBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"DLT8000",
+   "DLT Tape [DLT8000]",
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   DLT4000Eject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"DLT7000",        
+   "DLT Tape [DLT7000]",
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   DLT4000Eject,
+   GenericClean,
+   GenericRewind,
+   GenericBarCode,
+   GenericSearch,
+   GenericSenseHandler},
+  {"DLT4000",        
+   "DLT Tape [DLT4000]",
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   DoNothing,
+   DLT4000Eject,
+   GenericClean,
+   GenericRewind,
+   NoBarCode, 
+   GenericSearch,
+   GenericSenseHandler},
+  {NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
+};           
+
+
+LogPageDecode_T DecodePages[] = {
+  {2,
+   "C1553A",
+   WriteErrorCountersPage},
+  {3,
+   "C1553A",
+   ReadErrorCountersPage},
+  {0x30,
+   "C1553A",
+   C1553APage30},
+  {0x37,
+   "C1553A",
+   C1553APage37},
+  {2,
+   "*",
+   WriteErrorCountersPage},
+  {3,
+   "*",
+   ReadErrorCountersPage},
+  {0x39,
+   "EXB-85058HE-0000",
+   EXB85058HEPage39},
+  {0x3c,
+   "EXB-85058HE-0000",
+   EXB85058HEPage3c},
+  {0, NULL, NULL}
+};
+
+
+int ElementStatusValid = 0;         /* Set if the READ ELEMENT STATUS was OK, an no error is pending */
+int LibModeSenseValid = 0;          /* Set if we did an scussefull MODE SENSE */
+
+char *SlotArgs = 0;
+/* Pointer to MODE SENSE Pages */
+char *pModePage = NULL;
+EAAPage_T *pEAAPage = NULL;
+DeviceCapabilitiesPage_T *pDeviceCapabilitiesPage = NULL;
+char *pVendorUnique = NULL;
+
+/*
+ *  New way, every element type has its on array
+ * which is dynamic allocated by the ElementStatus function,
+*/
+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; 
+
+char *chgscsi_datestamp = NULL;       /* Result pointer for tape_rdlabel */       
+char *chgscsi_label = NULL;           /* Result pointer for tape_rdlabel */
+char *chgscsi_result = NULL;          /* Needed for the result string of MapBarCode */
+
+/*
+ * First all functions which are called from extern
+ */
+
+
+/*
+ * Print the scsi-changer-driver version
+ */
+
+void ChangerDriverVersion()
+{
+  DebugPrint(DEBUG_ERROR, SECTION_INFO, "scsi-changer-driver: %s\n",rcsid);
+  SCSI_OS_Version();
+}
+
+/*
+ * Try to generate an template which can be used as an example for the config file
+ *
+ */
+void PrintConf()
+{
+  extern OpenFiles_T *pDev;
+  int count;
+  char *cwd;
+
+  printf("# Please replace every ??? with the correct parameter. It is not possible\n");
+  printf("# to guess everything :-)\n");
+  printf("# If the option is not needed, cleanmax for example if you have no cleaning\n");
+  printf("# tape remove the line.\n");
+  printf("#\n");
+  printf("number_configs   1   # Number of configs, you can have more than 1 config\n");
+  printf("                     # if you have for example more than one drive, or you\n");
+  printf("                     # to split your lib to use different dump levels\n");
+  printf("                     #\n");
+  printf("emubarcode       1   # If you drive has no barcode reader this will try\n");
+  printf("                     # keep an inventory of your tapes to find them faster\n");
+  printf("                     #\n");
+  printf("havebarcode      0   # Set this to 1 if you have an library with an installed\n");
+  printf("                     # barcode reader\n");
+  printf("                     #\n");
+  printf("debuglevel       0:0 # For debuging, see the docs /docs/TAPE-CHANGER\n");
+  printf("                     #\n");
+  printf("eject            ??? # set this to 1 if your drive needs an eject before move\n");
+  printf("                     #\n");
+  printf("sleep            ??? # How long to wait after an eject command before moving\n");
+  printf("                     # the tape\n");
+  printf("                     #\n");
+  
+  for (count = 0; count < CHG_MAXDEV ; count++)
+    {
+      if (pDev[count].dev)
+       {
+         if (pDev[count].inquiry != NULL && pDev[count].inquiry->type == TYPE_CHANGER)
+           {
+             printf("changerdev   %s # This is the device to communicate with the robot\n", pDev[count].dev);
+             break;
+           }
+       }
+    }
+  
+  /*
+   * Did we reach the end of the list ?
+   * If no we found an changer and now we try to
+   * get the element status for the count of slots
+   */
+  if (count < CHG_MAXDEV)
+    {
+      pDev[count].functions->function_status(count, 1);  
+    } else {
+      printf("changerdev   ??? # Ups nothing found. Please check the docs\n");
+    }
+  
+  printf("                     #\n");
+  printf("                     # Here now comes the config for the first tape\n");
+  printf("config             0 # This value is the one which is used in the amanda\n");
+  printf("                     # config file to tell the chg-scsi programm which tape\n");
+  printf("                     # and which slots to use\n");
+  printf("                     #\n");
+  printf("cleancart        ??? # The slot where the cleaning tape is located\n");
+  printf("                     # remove it if you have no cleaning tape\n");
+  printf("                     #\n");
+  printf("drivenum           0 # Which tape drive to use if there are more than one drive\n");
+  printf("                     #\n");
+  printf("dev              ??? # Which is the raw device to read/write data from the tape\n");
+  printf("                     # It is important to use the non rewinding tape, like\n");
+  printf("                     # /dev/nrst0 on linux, /dev/nrsa0 on BSD ....\n");
+  printf("                     #\n");
+
+  /*
+   * OK now lets see if we have an direct SCSI channel
+   * to the tape
+   * If not thats not a problem
+   */
+  for (count = 0; count < CHG_MAXDEV; count++)
+    {
+      if (pDev[count].dev)
+       {
+         if (pDev[count].inquiry != NULL && pDev[count].inquiry->type == TYPE_TAPE)
+           {
+             printf("scsitapedev   %s # This is the device to communicate with the tape\n", pDev[count].dev);
+             printf("                     # to get some device stats, not so importatn, and\n");
+             printf("                     # if you run in problems delete it complete\n");
+             printf("                     #\n");
+             break;
+           }
+       }
+    }
+
+
+  if (STE != 0)
+    {
+      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);
+    } else {
+      printf("startuse         ??? # Which is the first slot to use\n");
+      printf("                     #\n");
+      printf("enduse           ??? # Which is the last slot to use\n");
+    }
+      printf("                     # decrement this value by 1 if you have an\n");
+      printf("                     # cleaning tape in the last slot\n");
+      printf("                     #\n");
+
+  cwd = getcwd(NULL, 0);
+  
+  printf("statfile %s/tape0-slot #\n",cwd);
+  printf("cleanfile %s/tape0-clean #\n", cwd);
+  printf("usagecount %s/tape0-totaltime #\n", cwd);
+  printf("tapestatus %s/tape0-tapestatus #\n", cwd);
+  printf("labelfile %s/labelfile #\n", cwd);
+}
+
+
+/*
+ * Try to create a list of tapes and labels which are in the current
+ * magazin. The drive must be empty !!
+ * 
+ * labelfile -> file name of the db
+ * drive -> which drive should we use
+ * eject -> the tape device needs an eject before move
+ * start -> start at slot start
+ * stop  -> stop at slot stop
+ * clean -> if we have an cleaning tape than this is the slot number of it
+ *
+ * return 
+ * 0  -> fail
+ * 1  -> successfull
+ *
+ * ToDo:
+ * Check if the tape/changer is ready for the next move
+ * 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)
+{
+  extern OpenFiles_T *pDev;
+  int x;
+  char *datestamp = malloc(1);   /* stupid, but tapefd_rdlabel does an free at the begining ... */
+  char *label = malloc(1);       /* the same here ..... */
+  char *result;                    /* Used to store the result of MapBarCode */
+  int barcode;                   /* cache the result from the BarCode function */
+  static int inv_done = 0;       /* Inventory function called ?, marker to disable recursion */
+  MBC_T *pbarcoderes = malloc(sizeof(MBC_T));    /* Here we will pass the parameter to MapBarCode and get the result */
+  
+  DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "##### START Inventory\n");
+  memset(pbarcoderes, 0 , sizeof(MBC_T));
+
+  if (inv_done != 0)
+    {
+      DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "##### STOP inv_done -> %d Inventory\n",inv_done);
+      return;
+    }
+  inv_done = 1;
+  barcode = BarCode(INDEX_CHANGER);
+  
+  pbarcoderes->action = RESET_VALID;
+
+  MapBarCode(labelfile,pbarcoderes);
+  
+  /*
+   * Check if an tape is loaded, if yes unload it
+   * and do an INIT ELEMENT STATUS
+   */
+  
+  if (pDTE[0].status == 'F')
+    {
+      if (eject)
+       {
+         eject_tape("", eject);
+       }
+      (void)unload(INDEX_TAPE, 0, 0);
+    }
+  
+  GenericResetStatus(INDEX_CHANGER);
+  for (x = 0; x < STE; x++)
+    {
+      if (x == clean)
+       {
+         continue;
+       }
+      
+      /*
+       * Load the tape, on error try the next
+       * error could be an empty slot for example
+       */
+      if (load(INDEX_CHANGER, drive, x ) != 0)
+       {
+         DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE, "Load drive(%d) from(%d) failed\n", drive, x);
+         continue;
+       }
+
+      /*
+       * Wait until the tape is ready
+       */
+      Tape_Ready(INDEX_TAPECTL, 60);
+
+      SCSI_CloseDevice(INDEX_TAPE);
+
+      if ((result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &datestamp, &label)) == NULL)
+      {
+       pbarcoderes->action = UPDATE_SLOT;
+       strcpy(pbarcoderes->data.voltag, label);
+       pbarcoderes->data.slot = x;
+       pbarcoderes->data.from = 0;
+       pbarcoderes->data.LoadCount = 1;
+       if (BarCode(INDEX_CHANGER) == 1)
+         {
+           strcpy(pbarcoderes->data.barcode, pDTE[drive].VolTag);
+           MapBarCode(labelfile, pbarcoderes);
+         } else {
+           MapBarCode(labelfile, pbarcoderes);
+         }
+      } else {
+       DebugPrint(DEBUG_ERROR,SECTION_MAP_BARCODE, "Read label failed\n");
+      }
+
+      if (eject)
+       {
+         eject_tape("", eject);
+       }
+
+      (void)unload(INDEX_TAPE, drive, x);
+    }
+  DebugPrint(DEBUG_INFO,SECTION_MAP_BARCODE, "##### STOP Inventory\n");
+}
+
+/*
+ * Check if the slot ist empty
+ * slot -> slot number to check
+ */
+int isempty(int fd, int slot)
+{
+  extern OpenFiles_T *pDev;
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### START isempty\n");
+
+  if (ElementStatusValid == 0)
+    {
+      if ( pDev[fd].functions->function_status(fd, 1) != 0)
+        {
+          DebugPrint(DEBUG_ERROR,SECTION_TAPE,"##### STOP isempty [-1]\n");
+          return(-1);
+        }
+    }
+
+  if (pSTE[slot].status == 'E')
+    {
+      DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP isempty [1]\n");
+      return(1);
+    }
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP isempty [0]\n");
+  return(0);
+}
+
+int get_clean_state(char *tapedev)
+{
+  extern OpenFiles_T *pDev;
+  /* Return 1 if cleaning is needed */
+  int ret;
+  
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### START get_clean_state\n");
+
+  if (pDev[INDEX_TAPECTL].SCSI == 0)
+    {
+      DebugPrint(DEBUG_ERROR,SECTION_TAPE,"##### STOP get_clean_state [-1]\n");
+      return(-1);
+    }
+  ret=pDev[INDEX_TAPECTL].functions->function_clean(tapedev);
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP get_clean_state [%d]\n", ret);
+  return(ret);    
+}
+
+/*
+ * eject the tape
+ * The parameter tapedev is not used.
+ * 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 */
+{
+  extern OpenFiles_T *pDev;
+  int ret = 0;
+  extern changer_t chg;         /* Needed for the infos about emubarcode and labelfile */
+
+  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_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
+       pDev[INDEX_TAPECTL].functions->function_rewind(INDEX_TAPECTL);
+      } else {
+       pDev[INDEX_TAPE].functions->function_rewind(INDEX_TAPE);
+      }
+
+      if (pDev[INDEX_TAPE].devopen == 1)
+       {
+         SCSI_CloseDevice(INDEX_TAPE);
+       }
+      
+      chgscsi_result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label);
+    }
+
+  if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail == 1 && type == 1)
+    {
+      ret=pDev[INDEX_TAPECTL].functions->function_eject(tapedev, type);
+      DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP (SCSI)eject_tape [%d]\n", ret);
+      return(ret);
+    }
+  
+  if (pDev[INDEX_TAPE].avail == 1)
+    {
+      ret=Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT);
+      DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP (ioctl)eject_tape [%d]\n", ret);
+      return(ret);
+    }
+
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"##### STOP eject_tape [-1]\n");
+  return(-1);
+}
+
+
+/* Find an empty slot, starting at start, ending at start+count */
+int find_empty(int fd, int start, int count)
+{
+  extern OpenFiles_T *pDev;
+  int x;
+  int end;
+
+  DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"###### START find_empty\n");
+
+  if (ElementStatusValid == 0)
+    {
+      if ( pDev[fd].functions->function_status(fd , 1) != 0)
+        {
+          DebugPrint(DEBUG_ERROR,SECTION_ELEMENT,"###### END find_empty [%d]\n", -1);
+          return(-1);
+        }
+    }
+  
+  if (count == 0)
+    {
+      end = STE;
+    } else {
+      end = start + count;
+    }
+  
+  if (end > STE)
+    {
+      end = STE;
+    }
+  
+  DebugPrint(DEBUG_INFO,SECTION_ELEMENT,"start at %d, end at %d\n", start, 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_ERROR,SECTION_ELEMENT,"###### END find_empty [%d]\n", -1);
+  return(-1);
+}
+
+/*
+ * See if the tape is loaded based on the information we
+ * got back from the ReadElementStatus
+ * return values
+ * -1 -> Error (Fatal)
+ * 0  -> drive is empty
+ * 1  -> drive is loaded
+ */
+int drive_loaded(int fd, int drivenum)
+{
+  extern OpenFiles_T *pDev;
+
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"###### START drive_loaded\n");
+  DebugPrint(DEBUG_INFO,SECTION_TAPE,"%-20s : fd %d drivenum %d \n", "drive_loaded", fd, drivenum);
+  
+  
+  if (ElementStatusValid == 0)
+    {
+      if (pDev[INDEX_CHANGER].functions->function_status(INDEX_CHANGER, 1) != 0)
+       {
+         DebugPrint(DEBUG_ERROR,SECTION_TAPE,"Fatal error\n");
+         return(-1);
+       }
+    }
+  
+  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);
+  }
+}
+
+
+/*
+ * unload the specified drive into the specified slot
+ * (storage element)
+ *
+ * TODO:
+ * Check if the MTE is empty
+ */
+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 = malloc(sizeof(MBC_T));
+
+  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);
+  memset(pbarcoderes, 0, sizeof(MBC_T));
+  
+  /*
+   * If the Element Status is not valid try to
+   * init it
+   */
+  if (ElementStatusValid == 0)
+    {
+      if (pDev[INDEX_CHANGER].functions->function_status(INDEX_CHANGER , 1) != 0)
+       {
+         DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Element Status not valid, reset failed\n");
+         DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1)\n");
+         return(-1);
+       }
+    }
+  
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"%-20s : unload drive %d[%d] slot %d[%d]\n", "unload", 
+            drive, 
+            pDTE[drive].address, 
+            slot, 
+            pSTE[slot].address);
+  
+  /*
+   * Unloading an empty tape unit makes no sense
+   * so return with an error
+   */
+  if (pDTE[drive].status == 'E')
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_TAPE,"unload : Drive %d address %d is empty\n", drive, pDTE[drive].address);
+      DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1)\n");
+      return(-1);
+    }
+  
+  /*
+   * If the destination slot is full
+   * try to find an enpty slot
+   */
+  if (pSTE[slot].status == 'F')  
+    {
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"unload : Slot %d address %d is full\n", drive, pSTE[slot].address);
+      if ( ElementStatusValid == 0)
+       {
+         DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "unload: Element Status not valid, can't find an empty slot\n");
+         return(-1);
+       }
+      
+      slot = find_empty(fd, 0, 0);
+      if (slot == -1 )
+      {
+             DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "unload: No Empty slot found\n");
+             return(-1);
+      }
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"unload : found empty one, try to unload to slot %d\n", slot);
+    }
+
+  
+
+  /*
+   * If eject is not set we must read the label info
+   */
+
+  if (chg.eject == 0)
+    {
+      if (pDev[INDEX_TAPE].avail == 1 && (chg.emubarcode == 1 || BarCode(INDEX_CHANGER)))
+       {
+
+         if (pDev[INDEX_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
+           pDev[INDEX_TAPECTL].functions->function_rewind(INDEX_TAPECTL);
+         } else {
+           pDev[INDEX_TAPE].functions->function_rewind(INDEX_TAPE);
+         }
+         
+         if (pDev[INDEX_TAPE].devopen == 1)
+           {
+             SCSI_CloseDevice(INDEX_TAPE);
+           }
+         
+         chgscsi_result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &chgscsi_datestamp, &chgscsi_label);
+       } 
+    }
+
+  /*
+   * Do the unload/move
+   */
+  ret = pDev[INDEX_CHANGER].functions->function_move(INDEX_CHANGER , pDTE[drive].address, pSTE[slot].address);
+
+  /*
+   * Update the Status
+   */
+  if (pDev[INDEX_CHANGER].functions->function_status(INDEX_CHANGER , 1) != 0)
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP unload (-1 update status failed)\n");
+      return(-1);
+    }
+     
+  /*
+   * Did we get an error from tape_rdlabel
+   * 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)
+  {
+    /*
+     * 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)
+      {
+       /* 
+        * 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
+        */
+       pbarcoderes->action = FIND_SLOT;
+       strcpy(pbarcoderes->data.voltag, chgscsi_label);
+       strcpy(pbarcoderes->data.barcode, pSTE[slot].VolTag );
+       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 */
+         {
+           do_inventory = 1;
+         } else {
+           if (slot != pbarcoderes->data.slot)
+             {
+               DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Slot DB out of sync, slot %d != map %d",slot, pbarcoderes->data.slot);
+               do_inventory = 1;
+             }
+         }
+      }
+  }
+
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP unload(0)\n");
+  return(0);
+}
+
+
+/*
+ * load the media from the specified element (slot) into the
+ * specified data transfer unit (drive)
+ * fd     -> pointer to the internal device structure pDev
+ * driver -> which drive in the library
+ * slot   -> the slot number from where to load
+ *
+ * return -> 0 = success
+ *           !0 = failure
+ */
+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 */
+  char *datestamp = NULL;       /* Result pointer for tape_rdlabel */       
+  char *label = NULL;           /* Result pointer for tape_rdlabel */
+  int ret;
+  extern OpenFiles_T *pDev;
+  extern int do_inventory;
+  MBC_T *pbarcoderes = malloc(sizeof(MBC_T));
+
+  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);
+  memset(pbarcoderes, 0 , sizeof(MBC_T));
+
+  if (ElementStatusValid == 0)
+      {
+          if (pDev[fd].functions->function_status(fd, 1) != 0)
+              {
+               DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1)\n");
+               DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
+               return(-1);
+              }
+      }
+
+  /*
+   * Check if the requested slot is in the range of available slots
+   * The library starts counting at 1, we start at 0, so if the request slot
+   * is ge than the value we got from the ModeSense fail with an return value
+   * of 2
+   */
+  if (slot >= STE)
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : slot %d ge STE %d\n",slot, STE); 
+      ChgExit("load", "slot >= STE", FATAL);
+    }
+  
+  /* 
+   * And the same for the tape drives
+   */
+  if (drive >= DTE)
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : drive %d ge DTE %d\n",drive, DTE); 
+      ChgExit("load", "drive >= DTE", FATAL);
+    }
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"load : load drive %d[%d] slot %d[%d]\n",drive,
+            pDTE[drive].address,
+            slot,
+            pSTE[slot].address);
+  
+  if (pDTE[drive].status == 'F')
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : Drive %d address %d is full\n", drive, pDTE[drive].address);
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
+      return(-1);
+    }
+  
+  if (pSTE[slot].status == 'E')
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"load : Slot %d address %d is empty\n", drive, pSTE[slot].address);
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
+      return(-1);
+    }
+  
+  ret = pDev[fd].functions->function_move(fd, pSTE[slot].address, pDTE[drive].address);
+
+  /*
+   * Update the Status
+   */
+  if (pDev[fd].functions->function_status(fd, 1) != 0)
+      {
+       DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"##### STOP load (-1 update status failed)\n");
+       return(-1);
+      }
+
+  /*
+   * 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_TAPECTL].SCSI == 1 && pDev[INDEX_TAPECTL].avail) {
+       pDev[INDEX_TAPECTL].functions->function_rewind(INDEX_TAPECTL);
+      } else {
+       pDev[INDEX_TAPE].functions->function_rewind(INDEX_TAPE);
+      }
+      
+      if (pDev[INDEX_TAPE].devopen == 1)
+       {
+         SCSI_CloseDevice(INDEX_TAPE);
+       }
+      
+      result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &datestamp, &label);
+    }
+  
+  /*
+   * Did we get an error from tape_rdlabel
+   * if no update the vol/label mapping
+   */
+  if (result  == NULL && chg.labelfile != NULL && 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, label);
+      pbarcoderes->data.slot = 0;
+      pbarcoderes->data.from = 0;
+      pbarcoderes->data.LoadCount = 0;
+      
+      
+      /*
+       * If we have an barcode reader we only do an update
+       * If emubarcode is set we check if the
+       * info in the DB is up to date, if no we set the do_inventory flag
+       */
+      
+      if (BarCode(INDEX_CHANGER) == 1 && chg.emubarcode == 0)
+       {
+         pbarcoderes->action = UPDATE_SLOT;
+         strcpy(pbarcoderes->data.barcode, pDTE[drive].VolTag);
+         pbarcoderes->data.LoadCount = 1;
+         pbarcoderes->data.slot = slot;
+         MapBarCode(chg.labelfile, pbarcoderes);
+       }
+      
+      if (BarCode(INDEX_CHANGER) == 0 && chg.emubarcode == 1)
+       {
+         pbarcoderes->action = FIND_SLOT;
+         if (MapBarCode(chg.labelfile, pbarcoderes) == 0) /* Nothing found, do an inventory */
+           {
+             do_inventory = 1;
+           } else { /* We got something, is it correct ? */
+             if (slot != pbarcoderes->data.slot && do_inventory == 0)
+               {
+                 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);
+               } else { /* OK, so increment the load count */
+                 pbarcoderes->action = UPDATE_SLOT;
+                 pbarcoderes->data.LoadCount = 1;
+                 pbarcoderes->data.slot = slot;
+                 MapBarCode(chg.labelfile, pbarcoderes);
+               }
+           }
+       }
+      
+      if (BarCode(INDEX_CHANGER) == 1 && chg.emubarcode == 1)
+       {
+         ChgExit("Load", "BarCode == 1 and emubarcode == 1", FATAL);
+       }
+      
+      DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP load (%d)\n",ret);
+      return(ret);
+    }
+    DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP load (%d)\n",ret);
+    return(ret);
+}
+
+/*
+ * Returns the number of Storage Slots which the library has
+ * fd -> pointer to the internal devie structure pDev
+ * return -> Number of slots
+ */ 
+int get_slot_count(int fd)
+{
+  extern OpenFiles_T *pDev;
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"###### START get_slot_count\n");
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"%-20s : fd %d\n", "get_slot_count", fd);
+
+  if (ElementStatusValid == 0)
+    {
+      pDev[fd].functions->function_status(fd, 1);
+    }
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### STOP get_slot_count (%d)\n",STE);
+  return(STE);
+  /*
+   * return the number of slots in the robot
+   * to the caller
+   */
+  
+}
+
+
+/*
+ * retreive the number of data-transfer devices /Tape drives)
+ * fd     -> pointer to the internal devie structure pDev
+ * return -> -1 on failure
+ */ 
+int get_drive_count(int fd)
+{
+
+  extern OpenFiles_T *pDev;
+
+  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)
+           {
+               DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Error getting drive count\n");
+               DebugPrint(DEBUG_ERROR, SECTION_SCSI, "##### STOP get_drive_count (-1)\n");
+               return(-1);
+           }
+      }
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP get_drive_count (%d drives)\n",DTE);
+  return(DTE);
+}
+
+/*
+ * Now the internal functions
+ */
+
+/*
+ * Open the device and placeit in the list of open files
+ * The OS has to decide if it is an SCSI Commands capable device
+ */
+
+int OpenDevice(int ip , char *DeviceName, char *ConfigName, char *ident)
+{
+  extern OpenFiles_T *pDev;
+  char tmpstr[15];
+  ChangerCMD_T *p = (ChangerCMD_T *)&ChangerIO;
+  
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START OpenDevice\n");
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"OpenDevice : %s\n", DeviceName);
+  
+  pDev[ip].ConfigName = stralloc(ConfigName);
+  pDev[ip].dev = stralloc(DeviceName);
+
+  if (SCSI_OpenDevice(ip) != 0 )
+    {
+      if (ident != NULL)   /* Override by config */
+      {
+        while(p->ident != NULL)
+          {
+            if (strcmp(ident, p->ident) == 0)
+              {
+                pDev[ip].functions = p;
+               strncpy(pDev[ip].ident, ident, 17);
+                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);
+              }
+            p++;
+          }
+         ChgExit("OpenDevice", "ident not found", FATAL);
+      } else {
+        while(p->ident != NULL)
+          {
+            if (strcmp(pDev[ip].ident, p->ident) == 0)
+              {
+                pDev[ip].functions = p;
+                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);
+              }
+            p++;
+          }
+      }
+      /* Nothing matching found, try generic */
+      /* 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);
+      while(p->ident != NULL)
+        {
+          if (strcmp(tmpstr, p->ident) == 0)
+            {
+              pDev[ip].functions = p;
+              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);
+            }
+          p++;
+        }  
+    } else { /* Something failed, lets see what */
+      DebugPrint(DEBUG_ERROR, SECTION_SCSI,"##### STOP OpenDevice failed\n");
+    }
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP OpenDevice (nothing found) !!\n");
+  return(0); 
+}
+
+
+/*
+ * This functions checks if the library has an barcode reader.
+ * fd     -> pointer to the internal devie structure pDev
+ */
+int BarCode(int fd)
+{
+  int ret = 0;
+  extern OpenFiles_T *pDev;
+
+  DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START BarCode\n");
+  DebugPrint(DEBUG_INFO, SECTION_BARCODE,"%-20s : fd %d\n", "BarCode", fd);
+
+  DebugPrint(DEBUG_INFO, SECTION_BARCODE,"Ident = [%s], function = [%s]\n", pDev[fd].ident,
+            pDev[fd].functions->ident);
+  ret = pDev[fd].functions->function_barcode(fd);
+  DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP BarCode (%d)\n",ret);
+  return(ret);
+}
+
+
+/*
+ * This functions check if the tape drive is ready
+ *
+ * fd     -> pointer to the internal devie structure pDev
+ * wait -> time to wait for the ready status
+ *
+ */
+int Tape_Ready(int fd, int wait_time)
+{
+  extern OpenFiles_T *pDev;
+  int true = 1;
+  int ret;
+  int cnt = 0;
+  
+  RequestSense_T *pRequestSense;
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START Tape_Ready\n");
+  
+  /*
+   * Which device should we use to get the 
+   * tape status
+   */
+
+  /*
+   * First the ioctl tapedevice
+   */
+  if (pDev[INDEX_TAPE].avail == 1)
+    {
+      fd = INDEX_TAPE;
+    }
+  
+  /*
+   * But if available and can do SCSI
+   * the scsitapedev
+   */
+  if (pDev[INDEX_TAPECTL].avail == 1 && pDev[INDEX_TAPECTL].SCSI == 1)
+    {
+      fd = INDEX_TAPECTL;
+    }
+  
+  if (pDev[fd].avail == 1 && pDev[fd].SCSI == 0)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : Can't send SCSI commands, try ioctl\n");
+      /*
+       * Do we get an non negative result.
+       * If yes this function is available
+       * and we can use it to get the status 
+       * of the tape
+       */
+      ret = Tape_Status(fd);
+      if (ret >= 0)
+       {
+         while (cnt < wait_time)
+           {
+             if ( ret & TAPE_ONLINE)
+               {
+                 DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready : Ready after %d seconds\n",cnt);
+                 DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n");
+                 return(0);
+               }
+             cnt++;
+             sleep(1);
+             ret = Tape_Status(fd);
+           }
+
+         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);
+         
+       } 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);
+       }
+    }
+  
+  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);
+    }
+  
+  /*
+   * Ignore errors at this point
+   */
+  GenericRewind(fd);
+  
+  /*
+   * Wait until we get an ready condition
+   */
+  
+  while (true && cnt < wait_time)
+    {
+      ret = SCSI_TestUnitReady(fd, pRequestSense );
+      switch (ret)
+       {
+       case SCSI_OK:
+         true = 0;
+         break;
+       case SCSI_SENSE:
+         switch (SenseHandler(fd, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+           {
+           case SENSE_NO:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_NO\n");
+             true=0;
+             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;
+             break;
+           case SENSE_ABORT:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeReady (TestUnitReady) SENSE_ABORT\n");
+             return(-1);
+             break;
+           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;
+             break;
+           }
+         break;
+       case SCSI_ERROR:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeReady (TestUnitReady) SCSI_ERROR\n");
+         return(-1);
+         break;
+       case SCSI_BUSY:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SCSI_BUSY\n");
+         break;
+       case SCSI_CHECK:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"TapeReady (TestUnitReady) SCSI_CHECK\n");
+         break;
+       default:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeReady (TestUnitReady) unknown (%d)\n",ret);
+         break;
+       }
+      sleep(1);
+      cnt++;
+    }
+
+  free(pRequestSense);
+
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"Tape_Ready after %d sec\n", cnt);
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP Tape_Ready\n"); 
+  return(0);
+}
+
+
+int DecodeSCSI(CDB_T CDB, char *string)
+{
+  SC_COM_T *pSCSICommand;
+  int x;
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI, "##### START DecodeSCSI\n");
+  pSCSICommand = (SC_COM_T *)&SCSICommand;
+
+  while (pSCSICommand->name != NULL)
+    {
+      if (CDB[0] == pSCSICommand->command)
+        {
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"%s %s", string, pSCSICommand->name);
+          for (x=0; x < pSCSICommand->length; x++)
+            {
+              DebugPrint(DEBUG_INFO, SECTION_SCSI," %02X", CDB[x]);
+            }
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"\n");
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP DecodeSCSI\n");
+          return(0);
+       }
+      pSCSICommand++;
+    }
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"Not found %X\n", CDB[0]);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP DecodeSCSI\n");
+  return(0);
+}
+
+int DecodeModeSense(char *buffer, int offset, char *pstring, char block, FILE *out)
+{
+  ReadWriteErrorRecoveryPage_T *prp;
+  DisconnectReconnectPage_T *pdrp;
+  int length = (unsigned char)*buffer - 4 - offset;
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START DecodeModeSense\n");
+
+  dump_hex(buffer, 255, DEBUG_INFO, SECTION_SCSI);
+
+  /* Jump over the Parameter List header  and an offset if we have something
+   * Unknown at the start (ADIC-218) at the moment
+   * 
+   */
+  buffer = buffer + 4 + offset;
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"buffer length = %d\n", length);
+
+  if (block) /* Do we have an block descriptor page ?*/
+    {
+      if (out != NULL)
+        fprintf(out, "DecodeModeSense : Density Code %x\n", buffer[0]);
+      buffer++;
+
+      if (out != NULL)
+       fprintf(out, "DecodeModeSense : Number of Blocks %d\n", V3(buffer));
+      buffer = buffer + 4;
+
+      if (out != NULL)
+       fprintf(out, "DecodeModeSense : Block Length %d\n", V3(buffer));
+      buffer = buffer + 3;
+    }
+  
+  while (length > 0)
+    {
+      switch (*buffer & 0x3f)
+        {
+        case 0:
+            pVendorUnique = buffer;
+            buffer++;
+            break;
+        case 0x1:
+          prp = (ReadWriteErrorRecoveryPage_T *)buffer;
+         if (out != NULL)
+          { 
+               fprintf(out, "DecodeModeSense : Read/Write Error Recovery Page\n");
+               fprintf(out,"\tTransfer Block            %d\n", prp->tb);
+               fprintf(out,"\tEnable Early Recovery     %d\n", prp->eer);
+               fprintf(out,"\tPost Error                %d\n", prp->per);
+               fprintf(out,"\tDisable Transfer on Error %d\n", prp->dte);
+               fprintf(out,"\tDisable ECC Correction    %d\n", prp->dcr);
+               fprintf(out,"\tRead Retry Count          %d\n", prp->ReadRetryCount);
+               fprintf(out,"\tWrite Retry Count         %d\n", prp->WriteRetryCount);
+         }
+          buffer++;
+          break;
+        case 0x2:
+          pdrp = (DisconnectReconnectPage_T *)buffer;
+         if (out != NULL)
+          {
+               fprintf(out, "DecodeModeSense : Disconnect/Reconnect Page\n");
+               fprintf(out,"\tBuffer Full Ratio     %d\n", pdrp->BufferFullRatio);
+               fprintf(out,"\tBuffer Empty Ratio    %d\n", pdrp->BufferEmptyRatio);
+               fprintf(out,"\tBus Inactivity Limit  %d\n", 
+                  V2(pdrp->BusInactivityLimit));
+               fprintf(out,"\tDisconnect Time Limit %d\n", 
+                  V2(pdrp->DisconnectTimeLimit));
+               fprintf(out,"\tConnect Time Limit    %d\n",
+                  V2(pdrp->ConnectTimeLimit));
+               fprintf(out,"\tMaximum Burst Size    %d\n",
+                  V2(pdrp->MaximumBurstSize));
+               fprintf(out,"\tDTDC                  %d\n", pdrp->DTDC);
+         }
+          buffer++;
+          break;
+        case 0x1d:
+          pEAAPage = (EAAPage_T *)buffer;
+         if (out != NULL)
+         {
+               fprintf(out,"DecodeModeSense : Element Address Assignment Page\n");
+               fprintf(out,"\tMedium Transport Element Address     %d\n", 
+                    V2(pEAAPage->MediumTransportElementAddress));
+               fprintf(out,"\tNumber of Medium Transport Elements  %d\n", 
+                    V2(pEAAPage->NoMediumTransportElements));
+               fprintf(out, "\tFirst Storage Element Address       %d\n", 
+                    V2(pEAAPage->FirstStorageElementAddress));
+               fprintf(out, "\tNumber of  Storage Elements         %d\n", 
+                    V2(pEAAPage->NoStorageElements));
+               fprintf(out, "\tFirst Import/Export Element Address %d\n", 
+                    V2(pEAAPage->FirstImportExportElementAddress));
+               fprintf(out, "\tNumber of  ImportExport Elements    %d\n", 
+                    V2(pEAAPage->NoImportExportElements));
+               fprintf(out, "\tFirst Data Transfer Element Address %d\n", 
+                    V2(pEAAPage->FirstDataTransferElementAddress));
+               fprintf(out, "\tNumber of  Data Transfer Elements   %d\n", 
+                    V2(pEAAPage->NoDataTransferElements));
+         }
+          buffer++;
+          break;
+        case 0x1f:
+          pDeviceCapabilitiesPage = (DeviceCapabilitiesPage_T *)buffer;
+         if (out != NULL)
+         {
+               fprintf(out, "DecodeModeSense : MT can store data cartridges %d\n",
+                    pDeviceCapabilitiesPage->MT);
+               fprintf(out, "DecodeModeSense : ST can store data cartridges %d\n",
+                    pDeviceCapabilitiesPage->ST);
+               fprintf(out, "DecodeModeSense : IE can store data cartridges %d\n",
+                    pDeviceCapabilitiesPage->IE);
+               fprintf(out, "DecodeModeSense : DT can store data cartridges %d\n",
+                    pDeviceCapabilitiesPage->DT);
+               fprintf(out, "DecodeModeSense : MT to MT %d\n",
+                    pDeviceCapabilitiesPage->MT2MT);
+               fprintf(out, "DecodeModeSense : MT to ST %d\n",
+                    pDeviceCapabilitiesPage->MT2ST);
+               fprintf(out, "DecodeModeSense : MT to IE %d\n",
+                    pDeviceCapabilitiesPage->MT2IE);
+               fprintf(out, "DecodeModeSense : MT to DT %d\n",
+                    pDeviceCapabilitiesPage->MT2DT);
+               fprintf(out, "DecodeModeSense : ST to MT %d\n",
+                    pDeviceCapabilitiesPage->ST2ST);
+               fprintf(out, "DecodeModeSense : ST to MT %d\n",
+                    pDeviceCapabilitiesPage->ST2ST);
+               fprintf(out, "DecodeModeSense : ST to DT %d\n",
+                    pDeviceCapabilitiesPage->ST2DT);
+               fprintf(out, "DecodeModeSense : IE to MT %d\n",
+                    pDeviceCapabilitiesPage->IE2MT);
+               fprintf(out, "DecodeModeSense : IE to ST %d\n",
+                    pDeviceCapabilitiesPage->IE2IE);
+               fprintf(out, "DecodeModeSense : IE to ST %d\n",
+                    pDeviceCapabilitiesPage->IE2DT);
+               fprintf(out, "DecodeModeSense : IE to ST %d\n",
+                    pDeviceCapabilitiesPage->IE2DT);
+               fprintf(out, "DecodeModeSense : DT to MT %d\n",
+                    pDeviceCapabilitiesPage->DT2MT);
+               fprintf(out, "DecodeModeSense : DT to ST %d\n",
+                    pDeviceCapabilitiesPage->DT2ST);
+               fprintf(out, "DecodeModeSense : DT to IE %d\n",
+                    pDeviceCapabilitiesPage->DT2IE);
+               fprintf(out, "DecodeModeSense : DT to DT %d\n",
+                    pDeviceCapabilitiesPage->DT2DT);
+         }
+          buffer++;
+          break;
+        default:
+          buffer++;  /* set pointer to the length information */
+          break;
+        }
+      /* Error if *buffer (length) is 0 */
+      if (*buffer == 0)
+        {
+          /*           EAAPage = NULL; */
+          /*           DeviceCapabilitiesPage = NULL; */
+          return(-1);
+        }
+      length = length - *buffer - 2;
+      buffer = buffer + *buffer + 1;      
+    }
+  return(0);
+}
+
+int DecodeSense(RequestSense_T *sense, char *pstring, FILE *out)
+{
+  if (out == NULL)
+    {
+      return(0);
+    }
+  fprintf(out,"##### START DecodeSense\n");
+  fprintf(out,"%sSense Keys\n", pstring);
+  if (sense->ErrorCode == 0x70)
+    {
+    fprintf(out,"\tExtended Sense                     \n");
+    } else {
+      fprintf(out,"\tErrorCode                     %02x\n", sense->ErrorCode);
+      fprintf(out,"\tValid                         %d\n", sense->Valid);
+    }
+  fprintf(out,"\tASC                           %02X\n", sense->AdditionalSenseCode);
+  fprintf(out,"\tASCQ                          %02X\n", sense->AdditionalSenseCodeQualifier);
+  fprintf(out,"\tSense key                     %02X\n", sense->SenseKey);
+  switch (sense->SenseKey)
+    {
+    case 0:
+      fprintf(out,"\t\tNo Sense\n");
+      break;
+    case 1:
+      fprintf(out,"\t\tRecoverd Error\n");
+      break;
+    case 2:
+      fprintf(out,"\t\tNot Ready\n");
+      break;
+    case 3:
+      fprintf(out,"\t\tMedium Error\n");
+      break;
+    case 4:
+      fprintf(out,"\t\tHardware Error\n");
+      break;
+    case 5:
+      fprintf(out,"\t\tIllegal Request\n");
+      break;
+    case 6:
+      fprintf(out,"\t\tUnit Attention\n");
+      break;
+    case 7:
+      fprintf(out,"\t\tData Protect\n");
+      break;
+    case 8:
+      fprintf(out,"\t\tBlank Check\n");
+      break;
+    case 9:
+      fprintf(out,"\t\tVendor uniq\n");
+      break;
+    case 0xa:
+      fprintf(out,"\t\tCopy Aborted\n");
+      break;
+    case 0xb:
+      fprintf(out,"\t\tAborted Command\n");
+      break;
+    case 0xc:
+      fprintf(out,"\t\tEqual\n");
+      break;
+    case 0xd:
+      fprintf(out,"\t\tVolume Overflow\n");
+      break;
+    case 0xe:
+      fprintf(out,"\t\tMiscompare\n");
+      break;
+    case 0xf:
+      fprintf(out,"\t\tReserved\n");
+      break;
+    }
+  return(0);      
+}
+
+int DecodeExtSense(ExtendedRequestSense_T *sense, char *pstring, FILE *out)
+{
+  ExtendedRequestSense_T *p;
+
+  fprintf(out,"##### START DecodeExtSense\n");
+  p = sense;
+
+  fprintf(out,"%sExtended Sense\n", pstring);
+  DecodeSense((RequestSense_T *)p, pstring, out);
+  fprintf(out,"\tLog Parameter Page Code         %02X\n", sense->LogParameterPageCode);
+  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->PF)
+        fprintf(out,"\tPower Fail\n");
+      if (sense->BPE)
+        fprintf(out,"\tSCSI Bus Parity Error\n");
+      if (sense->FPE)
+        fprintf(out,"\tFormatted Buffer parity Error\n");
+      if (sense->ME)
+        fprintf(out,"\tMedia Error\n");
+      if (sense->ECO)
+        fprintf(out,"\tError Counter Overflow\n");
+      if (sense->TME)
+        fprintf(out,"\tTapeMotion Error\n");
+      if (sense->TNP)
+        fprintf(out,"\tTape Not Present\n");
+      if (sense->LBOT)
+        fprintf(out,"\tLogical Beginning of tape\n");
+      if (sense->TMD)
+        fprintf(out,"\tTape Mark Detect Error\n");
+      if (sense->WP)
+        fprintf(out,"\tWrite Protect\n");
+      if (sense->FMKE)
+        fprintf(out,"\tFilemark Error\n");
+      if (sense->URE)
+        fprintf(out,"\tUnder Run Error\n");
+      if (sense->WEI)
+        fprintf(out,"\tWrite Error 1\n");
+      if (sense->SSE)
+        fprintf(out,"\tServo System Error\n");
+      if (sense->FE)
+        fprintf(out,"\tFormatter Error\n");
+      if (sense->UCLN)
+        fprintf(out,"\tCleaning Cartridge is empty\n");
+      if (sense->RRR)
+        fprintf(out,"\tReverse Retries Required\n");
+      if (sense->CLND)
+        fprintf(out,"\tTape Drive has been cleaned\n");
+      if (sense->CLN)
+        fprintf(out,"\tTape Drive needs to be cleaned\n");
+      if (sense->PEOT)
+        fprintf(out,"\tPhysical End of Tape\n");
+      if (sense->WSEB)
+        fprintf(out,"\tWrite Splice Error\n");
+      if (sense->WSEO)
+        fprintf(out,"\tWrite Splice Error\n");
+      fprintf(out,"\tRemaing 1024 byte tape blocks   %d\n", V3((char *)sense->RemainingTape));
+      fprintf(out,"\tTracking Retry Counter          %02X\n", sense->TrackingRetryCounter);
+      fprintf(out,"\tRead/Write Retry Counter        %02X\n", sense->ReadWriteRetryCounter);
+      fprintf(out,"\tFault Sympton Code              %02X\n", sense->FaultSymptomCode);
+    }
+  return(0);
+}
+
+int PrintInquiry(SCSIInquiry_T *SCSIInquiry)
+{
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START PrintInquiry\n");
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %x\n", "qualifier", SCSIInquiry->qualifier);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %x\n", "type", SCSIInquiry->type);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %x\n", "data_format", SCSIInquiry->data_format);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %X\n", "ansi_version", SCSIInquiry->ansi_version);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %X\n", "ecma_version", SCSIInquiry->ecma_version);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %X\n", "iso_version", SCSIInquiry->iso_version);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %X\n", "type_modifier", SCSIInquiry->type_modifier);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %x\n", "removable", SCSIInquiry->removable);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %.8s\n", "vendor_info", SCSIInquiry->vendor_info);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %.16s\n", "prod_ident", SCSIInquiry->prod_ident);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %.4s\n", "prod_version", SCSIInquiry->prod_version);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"%-15s %.19s\n", "vendor_specific", SCSIInquiry->vendor_specific);
+  return(0);
+}
+
+
+int DoNothing()
+{
+  dbprintf(("##### START DoNothing\n"));
+  return(0);
+}
+
+int GenericFree()
+{
+  dbprintf(("##### START GenericFree\n"));
+  return(0);
+}
+
+int GenericSearch()
+{
+  dbprintf(("##### START GenericSearch\n"));
+  return(0);
+}
+
+int TreeFrogBarCode(int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+
+  ModePageTreeFrogVendorUnique_T *pVendor;
+
+  dbprintf(("##### START TreeFrogBarCode\n"));
+  if (pModePage == NULL)
+    {
+      if ((pModePage = malloc(0xff)) == NULL)
+        {
+          dbprintf(("TreeFrogBarCode : malloc failed\n"));
+          return(-1);
+        }
+    }
+  
+  if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x0, 0x3f) == 0)
+    {
+      DecodeModeSense(pModePage, 0, "TreeFrogBarCode :", 0, debug_file);
+      
+      if (pVendorUnique == NULL)
+      {
+         dbprintf(("TreeFrogBarCode : no pVendorUnique\n"));
+         return(0);
+      }
+      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);
+      return(pVendor->EBARCO);
+    }
+  return(0);
+}
+
+int EXB_BarCode(int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+
+  ModePageEXB120VendorUnique_T *pVendor;
+  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);
+        }
+      if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
+       {
+         DecodeModeSense(pModePage, 0, "EXB_BarCode :", 0, debug_file);
+         LibModeSenseValid = 1;
+       } else {
+         LibModeSenseValid = -1;
+       }
+    }
+  
+  if (LibModeSenseValid == 1)
+    {
+      if (pVendorUnique == NULL)
+       {
+         DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : no pVendorUnique\n");
+         return(0);
+      }
+      pVendor = ( ModePageEXB120VendorUnique_T *)pVendorUnique;
+    
+      DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : NBL %d\n", pVendor->NBL);
+      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);
+            }
+          DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : setting NBL to 1\n");
+          memcpy(pVendorWork, pVendor, 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)
+            {
+              DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : SCSI_ModeSelect OK\n");
+              /* Hack !!!!!!
+               */
+              pVendor->NBL = 0;
+              
+              /* And now again !!!
+               */
+              GenericResetStatus(DeviceFD);
+            } else {
+              DebugPrint(DEBUG_INFO, SECTION_BARCODE,"EXB_BarCode : SCSI_ModeSelect failed\n");
+            }
+        }
+      dump_hex((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)
+{
+  DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START NoBarCode\n");
+  DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP  NoBarCode\n");
+  return(0);
+}
+
+int GenericBarCode(int DeviceFD)
+{
+  extern changer_t chg;
+  
+  DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### START GenericBarCode\n");
+  if ( chg.havebarcode  >= 1)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_BARCODE,"##### STOP GenericBarCode (havebarcode) => %d\n",chg.havebarcode);
+      return(1);
+    }
+  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)
+{
+  extern OpenFiles_T *pDev;
+  int ret = 0;
+  dbprintf(("##### START SenseHandler\n"));
+  if (pDev[DeviceFD].inqdone == 1)
+    {
+      dbprintf(("Ident = [%s], function = [%s]\n", pDev[DeviceFD].ident,
+               pDev[DeviceFD].functions->ident));
+      ret = pDev[DeviceFD].functions->function_error(DeviceFD, flag, SenseKey, AdditionalSenseCode, AdditionalSenseCodeQualifier, buffer);
+    } else {
+      dbprintf(("    Ups no sense\n"));
+    }
+  dbprintf(("#### STOP SenseHandler\n"));
+  return(ret);
+}
+
+/*
+ * Try to get information about the tape,
+ * Tape loaded ? Online etc
+ * Use the mtio ioctl to get the information if no SCSI Path
+ * to the tape drive is available.
+ *
+ * TODO:
+ * Pass an parameter to identify which unit to use
+ * if there are more than one
+ * Implement the SCSI path if available
+*/
+int TapeStatus()
+{
+  extern OpenFiles_T *pDev;
+  int ret;
+  int true = 1;
+  int cnt = 0;
+  RequestSense_T *pRequestSense;
+
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START TapeStatus\n");
+
+  /*
+   * If it is an device which understand SCSI commands the
+   * normal ioctl (MTIOCGET for example) may fail
+   * So try an Inquiry
+   */
+  if (pDev[INDEX_TAPECTL].SCSI == 1)
+    {
+      if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
+       {
+         dbprintf(("%-20s : malloc failed\n","TapeStatus"));
+         return(-1);
+       }
+      
+      while (true && cnt < 60)
+       {
+         ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
+         DebugPrint(DEBUG_INFO, SECTION_SCSI, "TapeStatus TestUnitReady ret %d\n",ret);
+         switch (ret)
+           {
+           case SCSI_OK:
+           case SCSI_SENSE:
+             switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)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;
+                 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;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_SCSI,"TapeStatus (TestUnitReady) SENSE_ABORT\n");
+                 true = 0;
+                 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;
+             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++;
+       }
+    } else {
+      ret = Tape_Status(INDEX_TAPE);
+      if ( ret & TAPE_ONLINE)
+       {
+         pDTE[0].status ='F'; 
+         DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### FULL\n");
+       } else {
+         pDTE[0].status = 'E';
+         DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### EMPTY\n");
+       }
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP TapeStatus\n");
+    }
+    return(0);
+}
+
+int DLT4000Eject(char *Device, int type)
+{
+  extern OpenFiles_T *pDev;
+
+  RequestSense_T *pRequestSense;
+  ExtendedRequestSense_T *pExtendedRequestSense;
+  int ret;
+  int cnt = 0;
+  int true = 1;
+
+  dbprintf(("##### START DLT4000Eject\n"));
+
+  if ((pRequestSense = malloc(sizeof(RequestSense_T))) == NULL)
+    {
+      dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
+      return(-1);
+    }
+
+  if ((pExtendedRequestSense = malloc(sizeof(ExtendedRequestSense_T))) == NULL)
+    {
+      dbprintf(("%-20s : malloc failed\n","DLT4000Eject"));
+      return(-1);
+    }
+    
+  if ( type > 1)
+    {
+      dbprintf(("DLT4000Eject : use mtio ioctl for eject on %s\n", pDev[INDEX_TAPE].dev));
+      return(Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT));
+    }
+  
+  
+  
+  if (pDev[INDEX_TAPECTL].SCSI == 0)
+    {
+      dbprintf(("DLT4000Eject : Device %s not able to receive SCSI commands\n", pDev[INDEX_TAPE].dev));
+      return(Tape_Ioctl(INDEX_TAPE, IOCTL_EJECT));
+    }
+  
+  
+  dbprintf(("DLT4000Eject : SCSI eject on %s = %s\n", pDev[INDEX_TAPECTL].dev, pDev[INDEX_TAPECTL].ConfigName));
+  
+  RequestSense(INDEX_TAPECTL, pExtendedRequestSense, 0); 
+  DecodeExtSense(pExtendedRequestSense, "DLT4000Eject : ", debug_file);
+  /* Unload the tape, 0 ==  wait for success
+   * 0 == unload 
+   */
+  ret = SCSI_LoadUnload(INDEX_TAPECTL, pRequestSense, 0, 0);
+
+  RequestSense(INDEX_TAPECTL, pExtendedRequestSense, 0); 
+  DecodeExtSense(pExtendedRequestSense, "DLT4000Eject : ", debug_file);
+  
+  /* < 0 == fatal */
+  if (ret < 0)
+    return(-1);
+  
+  if ( ret > 0)
+    {
+    }
+  
+  true = 1;
+  
+  
+  while (true && 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;
+         break;
+       case SCSI_SENSE:
+         switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+           {
+           case SENSE_NO:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_NO\n");
+             true = 0;
+             break;
+           case SENSE_TAPE_NOT_ONLINE:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
+             true = 0;
+             break;
+           case SENSE_IGNORE:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_IGNORE\n");
+             true = 0;
+             break;
+           case SENSE_ABORT:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SENSE_ABORT\n");
+             return(-1);
+             break;
+           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;
+             break;
+           }
+         break;
+       case SCSI_ERROR:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SCSI_ERROR\n");
+         return(-1);
+         break;
+       case SCSI_BUSY:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SCSI_BUSY\n");
+         break;
+       case SCSI_CHECK:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"DLT4000Eject (TestUnitReady) SCSI_CHECK\n");
+         break;
+       default:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"DLT4000Eject (TestUnitReady) unknown (%d)\n",ret);
+         break;
+       }
+      
+      cnt++;
+      sleep(2);
+    }
+  
+  
+  free(pRequestSense);
+  
+  dbprintf(("DLT4000Eject : Ready after %d sec, true = %d\n", cnt * 2, true));
+  return(0);
+  
+}
+
+/*
+ * Ejects an tape either with the ioctl interface
+ * or by using the SCSI interface if available.
+ *
+ * TODO:
+ * Before unload check if there is an tape in the drive
+ *
+ */
+int GenericEject(char *Device, int type)
+{
+  extern OpenFiles_T *pDev;
+  RequestSense_T *pRequestSense;
+  int ret;
+  int cnt = 0;
+  int true = 1;
+  
+  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);
+    }
+    
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericEject : SCSI eject on %s = %s\n", pDev[INDEX_TAPECTL].dev, pDev[INDEX_TAPECTL].ConfigName);
+  
+  /*
+   * Can we use SCSI commands ?
+   */
+  if (pDev[INDEX_TAPECTL].SCSI == 1)
+    {
+      LogSense(INDEX_TAPECTL);
+      /* 
+       * Unload the tape, 1 == don't wait for success
+       * 0 == unload 
+       */
+      ret = SCSI_LoadUnload(INDEX_TAPECTL, pRequestSense, 1, 0);
+      
+      /* < 0 == fatal */
+      if (ret < 0)
+       return(-1);
+      
+      if ( ret > 0)
+       {
+       }
+      
+      true = 1;
+      
+      
+      while (true && cnt < 300)
+       {
+         ret = SCSI_TestUnitReady(INDEX_TAPECTL, pRequestSense);
+         DebugPrint(DEBUG_INFO, SECTION_SCSI, "GenericEject TestUnitReady ret %d\n",ret);
+         switch (ret)
+           {
+           case SCSI_OK:
+           case SCSI_SENSE:
+             switch (SenseHandler(INDEX_TAPECTL, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)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;
+                 break;
+               case SENSE_IGNORE:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_IGNORE\n");
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_ABORT\n");
+                 return(-1);
+                 break;
+               case SENSE_RETRY:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SENSE_RETRY\n");
+                 break;
+               default:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) default (SENSE)\n");
+                 break;
+               }
+             break;
+           case SCSI_ERROR:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericEject (TestUnitReady) SCSI_ERROR\n");
+             return(-1);
+             break;
+           case SCSI_BUSY:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SCSI_BUSY\n");
+             break;
+           case SCSI_CHECK:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericEject (TestUnitReady) SCSI_CHECK\n");
+             break;
+           default:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericEject (TestUnitReady) unknown (%d)\n",ret);
+             break;
+           }  
+         cnt++;
+         sleep(2);
+       }
+      
+      free(pRequestSense);
+      
+    } else {
+      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);
+  return(0);
+}
+
+/*
+ * Rewind the tape 
+ *
+ * TODO:
+ * Make the retry counter an config option,
+ *
+ * Return:
+ * -1 -> error
+ * 0  -> success
+ */
+int GenericRewind(int DeviceFD)
+{
+  CDB_T CDB;
+  extern OpenFiles_T *pDev; 
+  RequestSense_T *pRequestSense;
+  char *errstr;                    /* Used by tape_rewind */
+  int ret;
+  int cnt = 0;
+  int true = 1;
+
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START GenericRewind pDEV -> %d\n",DeviceFD);
+
+
+  /*
+   * If we can use the SCSI device than use it, else use the ioctl
+   * function
+   */
+  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);
+       }
+      /*
+       * Before doing the rewind check if the tape is ready to accept commands
+       */
+      
+      while (true == 1)
+       {
+         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;
+             break;
+                   case SCSI_SENSE:
+             switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+               {
+               case SENSE_NO:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_NO\n");
+                 true = 0;
+                 break;
+               case SENSE_TAPE_NOT_ONLINE:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
+                 return(-1);
+                 break;
+               case SENSE_IGNORE:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_IGNORE\n");
+                 true = 0;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_ABORT\n");
+                 return(-1);
+                 break;
+               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;
+                 break;
+               }  /* switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey.... */
+             break;
+
+           case SCSI_ERROR:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_ERROR\n");
+             return(-1);
+             break;
+           case SCSI_BUSY:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_BUSY\n");
+             break;
+           case SCSI_CHECK:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_CHECK\n");
+             break;
+           default:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) unknown (%d)\n",ret);
+             break;
+           }
+         
+         sleep(1);
+         DebugPrint(DEBUG_INFO, SECTION_TAPE," Wait .... (%d)\n",cnt);
+         if (cnt > 180)
+           {
+             DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP GenericRewind (-1)\n");
+             return(-1);
+           }
+       } /* while true == 1 */
+      
+      cnt = 0;
+      true = 1;
+      
+      CDB[0] = SC_COM_REWIND;
+      CDB[1] = 1;             
+      CDB[2] = 0;
+      CDB[3] = 0;
+      CDB[4] = 0;
+      CDB[5] = 0;
+      
+      while (true)
+       {
+         ret = SCSI_Run(DeviceFD, Input, CDB, 6,
+                        NULL, 0, 
+                        (char *) pRequestSense,
+                        sizeof(RequestSense_T));
+         
+         DecodeSense(pRequestSense, "GenericRewind : ", debug_file);
+         
+         if (ret > 0) 
+           {
+             if (pRequestSense->SenseKey != UNIT_ATTENTION)
+               {
+                 true = 0;
+               }
+           }
+         if (ret == 0)
+           {
+             true = 0;
+           }
+         if (ret < 0)
+           {
+             DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : failed %d\n", ret);
+             true = 0;
+           }
+       }
+      
+      true = 1;
+      
+      while (true && 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;
+             break;
+           case SCSI_SENSE:
+             switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+               {
+               case SENSE_NO:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_NO\n");
+                 true = 0;
+                 break;
+               case SENSE_TAPE_NOT_ONLINE:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
+                 return(-1);
+                 break;
+               case SENSE_IGNORE:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_IGNORE\n");
+                 true = 0;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SENSE_ABORT\n");
+                 return(-1);
+                 break;
+               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;
+                 break;
+               }
+             break;
+           case SCSI_ERROR:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_ERROR\n");
+             return(-1);
+             break;     
+           case SCSI_BUSY:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_BUSY\n");
+             break;
+           case SCSI_CHECK:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"GenericRewind (TestUnitReady) SCSI_CHECK\n");
+             break;
+           default:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"GenericRewind (TestUnitReady) unknown (%d)\n",ret);
+             break;
+           }
+
+         cnt++;
+         sleep(2);
+       }
+      
+      free(pRequestSense);
+      
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : Ready after %d sec, true = %d\n", cnt * 2, true);
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (0)\n");
+    } else {
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"GenericRewind : use ioctl rewind\n");
+      if (pDev[DeviceFD].devopen == 1) 
+       {
+         DebugPrint(DEBUG_INFO, SECTION_TAPE,"Close Device\n");
+         SCSI_CloseDevice(DeviceFD);
+       }
+      /*
+       * Hmm retry it if it fails ?
+       */
+      cnt = 0;
+      true = 1;
+      while (true) 
+       {
+         if ((errstr = tape_rewind(pDev[DeviceFD].dev)) == NULL)
+           {
+             true = 0;
+             DebugPrint(DEBUG_INFO, SECTION_TAPE,"Rewind OK, (after %d tries)\n", cnt);
+           } else {
+             DebugPrint(DEBUG_INFO, SECTION_TAPE,"Rewind failed %s\n",errstr);
+             /*
+              * DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP GenericRewind (-1)\n");
+              * return(-1);
+              */
+             cnt++;
+             sleep(1);
+             if (cnt > 60)
+               {
+                 DebugPrint(DEBUG_ERROR, SECTION_TAPE,"##### STOP GenericRewind (-1), retry limit reached\n");
+                 return(-1);
+               }
+           }
+       }
+      DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericRewind (0)\n");
+    }
+
+  return(0);
+}
+
+
+/*
+ * Check if the tape has the tape clean
+ * bit set in the return of an request sense
+ *
+ */
+int GenericClean(char * Device)
+{
+  extern OpenFiles_T *pDev;
+  ExtendedRequestSense_T ExtRequestSense;
+  int ret = 0;
+
+  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);
+      }
+
+  /*
+   * Request Sense Data, reset the counter
+   */
+  if ( RequestSense(INDEX_TAPECTL, &ExtRequestSense, 1) == 0)
+    {
+      
+      DecodeExtSense(&ExtRequestSense, "GenericClean : ", debug_file);
+      if(ExtRequestSense.CLN) {
+       ret = 1;
+      } else {
+       ret = 0;
+      }
+    } else {
+      DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Got error from RequestSense\n");
+    }
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP GenericClean (%d)\n",ret);
+  return(ret);
+}
+
+int GenericResetStatus(int DeviceFD)
+{
+  CDB_T CDB;
+  RequestSense_T *pRequestSense;
+  int ret = 0;
+  int retry = 1;
+  
+  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);
+      }
+
+  while (retry)
+    {
+      CDB[0] = SC_COM_IES;   /* */
+      CDB[1] = 0;
+      CDB[2] = 0;
+      CDB[3] = 0;
+      CDB[4] = 0;
+      CDB[5] = 0;
+
+
+      ret = SCSI_Run(DeviceFD, Input, CDB, 6,
+                                NULL, 0,
+                                (char *) 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]); */
+          /*        fprintf(stderr, "\n");    */
+          return(ret);
+        }
+      if ( ret > 0 )
+        {
+          switch (SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+            {
+            case SENSE_IGNORE:
+              return(0);
+              break;
+            case SENSE_ABORT:
+              return(-1);
+              break;
+            case SENSE_RETRY:
+              retry++;
+              if (retry < MAX_RETRIES )
+                {
+                  DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "GenericResetStatus : retry %d\n", retry);
+                  sleep(2);
+                } else {
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus : return (-1)\n");
+                  return(-1);
+                }
+              break;
+            default:
+             DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericResetStatus :  (default) return (-1)\n");
+              return(-1);
+              break;
+            }
+        }
+      if (ret == 0)
+        retry = 0;
+    }
+  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "##### STOP GenericResetStatus (%d)\n",ret);
+  return(ret);
+}
+
+/* GenericSenseHandler
+ * Handles the conditions/sense wich is returned by an SCSI command
+ * pwork is an pointer to the structure OpenFiles_T, which is filled with information
+ * about the device to which we talk. Information are for example
+ * The vendor, the ident, which fd, etc. This strucure is filled when we open the
+ * device 
+ * flag tells how to handle the information passed in the buffer,
+ * 0 -> Sense Key available
+ * 1 -> No Sense key available
+ * buffer is a pointer to the data from the request sense result.
+ *
+ * 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)
+{ 
+  extern OpenFiles_T *pDev;
+  RequestSense_T *pRequestSense = (RequestSense_T *)buffer;
+  int ret = 0;
+  unsigned char *info = NULL;
+  
+  dbprintf(("##### START GenericSenseHandler\n"));
+  
+  DecodeSense(pRequestSense, "GenericSenseHandler : ", debug_file);
+  
+  ret = Sense2Action(pDev[ip].ident,
+                    pDev[ip].inquiry->type,
+                    flag, SenseKey,
+                    AdditionalSenseCode,
+                    AdditionalSenseCodeQualifier,
+                    (char **)&info);
+  
+  dbprintf(("##### STOP GenericSenseHandler\n"));
+  return(ret);
+}
+
+/*
+ * Do the move. We don't address the MTE element (the gripper)
+ * here. We assume that the library use the right MTE.
+ * The difference to GenericMove is that we do an align element
+ * before the move.
+ *
+ * Return:
+ *         == 0 -> success
+ *         != 0 -> error either from the SCSI command or from
+ *                 the element handling 
+ * TODO:
+*/
+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 SDX_MTE = 0;      /* This are parameters  passed */
+  int SDX_STE = -1;     /* to                          */
+  int SDX_DTE = -1;     /* AlignElements               */
+
+  DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### START SDXMove\n");
+  
+  DebugPrint(DEBUG_INFO, SECTION_MOVE,"%-20s : from = %d, to = %d\n", "SDXMove", from, to);
+
+  
+  if ((pfrom = LookupElement(from)) == NULL)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : ElementInfo for %d not found\n", from);
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
+      return(-1);
+    }
+  
+  if ((pto = LookupElement(to)) == NULL)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : ElementInfo for %d not found\n", to);
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
+      return(-1);
+    }
+  
+  if (pfrom->status == 'E') 
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : from %d is empty\n", from);
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
+      return(-1);
+    }
+
+  if (pto->status == 'F') 
+    {
+      switch (pto->status)
+      {
+         case CHANGER:
+           break;
+         case STORAGE:
+           DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : Destination Element %d Type %d is full\n",
+                pto->address, pto->type);
+            to = find_empty(DeviceFD, 0, 0);
+           if (to == -1 )
+           {
+                   DebugPrint(DEBUG_ERROR, SECTION_MOVE,"SDXMove : no empty slot found for unload\n");
+                   return(-1);
+           }
+            DebugPrint(DEBUG_INFO, SECTION_MOVE,"SDXMove : Unload to %d\n", to);
+            if ((pto = LookupElement(to)) == NULL)
+            {
+             DebugPrint(DEBUG_INFO, SECTION_MOVE, "SDXMove : ElementInfo for %d not found\n", to);
+             DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
+             return(-1);
+            }
+           break;
+         case IMPORT:
+           break;
+         case TAPETYPE:
+           break;
+      }
+    }
+
+  moveok = CheckMove(pfrom, pto);
+
+  switch (pto->type)
+  {
+    case TAPETYPE:
+      SDX_DTE = pto->address;
+      break;
+    case STORAGE:
+     SDX_STE = pto->address;
+     break;
+    case IMPORT:
+     SDX_STE = pto->address;
+     break;
+  }
+
+  switch (pfrom->type)
+  {
+    case TAPETYPE:
+      SDX_DTE = pfrom->address;
+      break;
+    case STORAGE:
+     SDX_STE = pfrom->address;
+     break;
+    case IMPORT:
+     SDX_STE = pfrom->address;
+     break;
+  }
+
+  if (SDX_DTE >= 0 && SDX_STE >= 0)
+  {
+    ret = SCSI_AlignElements(DeviceFD, SDX_MTE, SDX_DTE, SDX_STE);
+    DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### SCSI_AlignElemnts ret = %d\n",ret);
+    if (ret != 0 )
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
+      return(-1);
+    }
+  } 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);
+  }
+
+  /* 
+   * If from is a tape we must check if it is loaded 
+   * and if yes we have to eject it                  
+  */
+  if (pfrom->type == TAPETYPE)
+  {
+    tapestat = Tape_Status(INDEX_TAPE);
+    if ( tapestat & TAPE_ONLINE)
+    {
+      if (pDev[INDEX_TAPECTL].SCSI == 1)
+      { 
+        ret = eject_tape(pDev[INDEX_TAPECTL].dev,1);
+      } else {
+        ret = eject_tape(pDev[INDEX_TAPE].dev,2);
+      }
+    }
+  }
+
+  if ( ret == 0)
+  {
+    ret = SCSI_Move(DeviceFD, 0, from, to);
+  } else {
+    DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
+    return(ret);
+  }
+  DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP SDXMove\n");
+  return(ret);
+}
+
+/*
+ * Do the move. We don't address the MTE element (the gripper)
+ * here. We assume that the library use the right MTE
+ *
+ * Return:
+ *         == 0 -> success
+ *         != 0 -> error either from the SCSI command or from
+ *                 the element handling 
+ * TODO:
+*/
+int GenericMove(int DeviceFD, int from, int to)
+{
+  ElementInfo_T *pfrom;
+  ElementInfo_T *pto;
+  int ret = 0;
+  
+  DebugPrint(DEBUG_INFO, SECTION_MOVE, "##### START GenericMove\n");
+  
+  DebugPrint(DEBUG_INFO, SECTION_MOVE, "%-20s : from = %d, to = %d\n", "GenericMove", from, to);
+  
+  
+  if ((pfrom = LookupElement(from)) == NULL)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : ElementInfo for %d not found\n", from);
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
+      return(-1);
+    }
+  
+  if ((pto = LookupElement(to)) == NULL)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : ElementInfo for %d not found\n", to);
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
+      return(-1);
+    }
+  
+  if (pfrom->status == 'E') 
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : from %d is empty\n", from);
+      DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
+      return(-1);
+    }
+  
+  if (pto->status == 'F') 
+    {
+      DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : Destination Element %d Type %d is full\n",
+                pto->address, pto->type);
+      to = find_empty(DeviceFD, 0, 0);
+      if ( to == -1)
+      {
+             DebugPrint(DEBUG_ERROR, SECTION_MOVE, "GenericMove : no empty slot found\n");
+             return(-1);
+      }
+      DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : Unload to %d\n", to);
+      if ((pto = LookupElement(to)) == NULL)
+        {
+          DebugPrint(DEBUG_ERROR, SECTION_MOVE, " Ups should not happen\n");
+         DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
+         return(-1);
+        }
+    }
+  
+  if (CheckMove(pfrom, pto))
+    {
+      ret = SCSI_Move(DeviceFD, 0, from, to);
+    }
+
+  DebugPrint(DEBUG_INFO, SECTION_MOVE, "GenericMove : SCSI_Move return (%d)\n", ret);
+  DebugPrint(DEBUG_INFO, SECTION_MOVE,"##### STOP GenericMove\n");
+  return(ret);
+}
+
+/*
+ * Check if a move based on the information we got from the Mode Sense command
+ * is legal
+ * Return Values:
+ * 1 => OK
+ * 0 => Not OK
+ */
+
+int CheckMove(ElementInfo_T *from, ElementInfo_T *to)
+{
+       int moveok = 0;
+
+       DebugPrint(DEBUG_INFO, SECTION_MOVE, "##### START CheckMove\n");
+       if (pDeviceCapabilitiesPage != NULL )
+         {
+           DebugPrint(DEBUG_INFO, SECTION_MOVE, "CheckMove : checking if move from %d to %d is legal\n", from->address, to->address);
+           switch (from->type)
+             {
+             case CHANGER:
+               DebugPrint(DEBUG_INFO, SECTION_MOVE, "CheckMove : MT2");
+               switch (to->type)
+                 {
+                 case CHANGER:
+                   if (pDeviceCapabilitiesPage->MT2MT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "MT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case STORAGE:
+                   if (pDeviceCapabilitiesPage->MT2ST == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "ST\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case IMPORT:
+                   if (pDeviceCapabilitiesPage->MT2IE == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "IE\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case TAPETYPE:
+                   if (pDeviceCapabilitiesPage->MT2DT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "DT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 default:
+                   break;
+                 }
+               break;
+             case STORAGE:
+               DebugPrint(DEBUG_INFO, SECTION_MOVE, "CheckMove : ST2");
+               switch (to->type)
+                 {
+                 case CHANGER:
+                   if (pDeviceCapabilitiesPage->ST2MT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "MT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case STORAGE:
+                   if (pDeviceCapabilitiesPage->ST2ST == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "ST\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case IMPORT:
+                   if (pDeviceCapabilitiesPage->ST2IE == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "IE\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case TAPETYPE:
+                   if (pDeviceCapabilitiesPage->ST2DT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "DT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 default:
+                   break;
+                 }
+               break;
+             case IMPORT:
+               DebugPrint(DEBUG_INFO, SECTION_MOVE, "CheckMove : IE2");
+               switch (to->type)
+                 {
+                 case CHANGER:
+                   if (pDeviceCapabilitiesPage->IE2MT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "MT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case STORAGE:
+                   if (pDeviceCapabilitiesPage->IE2ST == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "ST\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case IMPORT:
+                   if (pDeviceCapabilitiesPage->IE2IE == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "IE\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case TAPETYPE:
+                   if (pDeviceCapabilitiesPage->IE2DT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "DT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 default:
+                   break;
+                 }
+               break;
+             case TAPETYPE:
+               DebugPrint(DEBUG_INFO, SECTION_MOVE, "CheckMove : DT2");
+               switch (to->type)
+                 {
+                 case CHANGER:
+                   if (pDeviceCapabilitiesPage->DT2MT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "MT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case STORAGE:
+                   if (pDeviceCapabilitiesPage->DT2ST == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "ST\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case IMPORT:
+                   if (pDeviceCapabilitiesPage->DT2IE == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "IE\n");
+                       moveok = 1;
+                     }
+                   break;
+                 case TAPETYPE:
+                   if (pDeviceCapabilitiesPage->DT2DT == 1)
+                     {
+                       DebugPrint(DEBUG_INFO, SECTION_MOVE, "DT\n");
+                       moveok = 1;
+                     }
+                   break;
+                 default:
+                   break;
+                 }
+               break;
+             default:
+               break;
+             }
+         } else {
+           DebugPrint(DEBUG_INFO, SECTION_MOVE, "CheckMove : pDeviceCapabilitiesPage == NULL");
+           /*
+             ChgExit("CheckMove", "DeviceCapabilitiesPage == NULL", FATAL);
+           */
+           moveok=1;
+         }
+       
+       DebugPrint(DEBUG_INFO, SECTION_MOVE, "###### STOP CheckMove\n");
+       return(moveok);
+}
+
+/*
+ */
+int GetCurrentSlot(int fd, int drive)
+{
+  extern OpenFiles_T *pDev;
+  int x;
+  dbprintf(("##### START GetCurrentSlot\n"));
+
+  if (pDev[0].SCSI == 0)
+      {
+          dbprintf(("GetCurrentSlot : can't send SCSI commands\n"));
+          return(-1);
+      }
+
+  if (ElementStatusValid == 0)
+    {
+      if (pDev[0].functions->function_status(0, 1) != 0)
+        {
+          return(-1);
+        }
+    }   
+
+  /* If the from address is the as the same as the tape address skip it */
+  if (pDTE[drive].from >= 0 && pDTE[drive].from != pDTE[drive].address)
+    {
+      for (x = 0; x < STE;x++)
+        {
+          if (pSTE[x].address == pDTE[drive].from)
+            return(x);
+        }
+      return(-1);
+    }
+
+  for (x = 0; x < STE;x++)
+    {
+      if (pSTE[x].status == 'E')
+        return(x);
+    }
+
+  /* Ups nothing loaded */
+  return(-1);
+}
+
+
+
+/*
+ * Reworked function to get the ElementStatus
+ * This function will first call the GetElementStatus
+ * function to get the Element status,
+ * and than check if there are abnormal conditions.
+ *
+ * If there are error conditions try to fix them
+ *
+ */
+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 */
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START GenericElementStatus\n");
+
+  if (pEAAPage == NULL)
+    {
+      /*
+       * If this pointer is null
+       * then try to read the parameter with MODE SENSE
+       *
+       */
+      if (pModePage == NULL && LibModeSenseValid == 0)
+        {
+          if ((pModePage = malloc(0xff)) == NULL)
+            {
+              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
+              return(-1);
+            }
+         if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
+           {
+             LibModeSenseValid = 1;
+             DecodeModeSense(pModePage, 0, "GenericElementStatus :", 0, debug_file);
+           } else {
+             DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GetElementStatus : failed SCSI_ModeSense\n");
+             LibModeSenseValid = -1;
+           }
+        }
+    }
+  
+  if (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]))
+               {
+               case SENSE_IES:
+                 MTEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on MTE\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      for (x = 0; x < IEE; x++)
+       {
+         if (pIEE[x].ASC > 0)
+           {
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&pIEE[x]))
+               {
+               case SENSE_IES:
+                 IEEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on IEE\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+
+      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]))
+               {
+               case SENSE_IES:
+                 STEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on IES\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      for (x = 0; x < DTE; x++)
+       {
+         if (pDTE[x].ASC > 0)
+           {
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+               {
+               case SENSE_IES:
+                 DTEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Abort on DTE\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      /*
+       * OK, we have an error, do an INIT ELMENT
+       * For the tape if not handled by the robot we have
+       * to do some extra checks
+       */
+      if (error == 1)
+       {
+         if (GenericResetStatus(DeviceFD) != 0)
+           {
+             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);
+           }
+         error = 0;
+       }
+
+      if (DTEError == 1)
+       {
+         TapeStatus();
+         /*
+          * If the status is empty to an move from tape to tape
+          * This is if the tape is ejected, but not unloaded
+          */
+         if (pDTE[0].status == 'E')
+           {
+             DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "GenericElementStatus : try to move tape to tape drive\n");
+             pDev[DeviceFD].functions->function_move(DeviceFD, pDTE[0].address, pDTE[0].address);
+           }
+       }
+         /* Done GetElementStatus */
+    }
+
+  if (error != 0)
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "GenericElementStatus : Can't init status (after loop)\n");
+      return(-1);
+    }
+
+  ElementStatusValid = 1;
+  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "#### STOP GenericElementStatus\n");
+  return(0);
+}
+
+
+/*
+ * 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 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 */
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START DLT448ElementStatus\n");
+
+  if (pEAAPage == NULL)
+    {
+      /*
+       * If this pointer is null
+       * then try to read the parameter with MODE SENSE
+       *
+       */
+      if (pModePage == NULL && LibModeSenseValid == 0)
+        {
+          if ((pModePage = malloc(0xff)) == NULL)
+            {
+              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"DLT448ElementStatus : malloc failed\n");
+              return(-1);
+            }
+         if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
+           {
+             LibModeSenseValid = 1;
+             DecodeModeSense(pModePage, 12, "DLT448ElementStatus :", 0, debug_file);
+           } else {
+             DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"DLT448ElementStatus : failed SCSI_ModeSense\n");
+             LibModeSenseValid = -1;
+           }
+        }
+    }
+  
+  if (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]))
+               {
+               case SENSE_IES:
+                 MTEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on MTE\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      for (x = 0; x < IEE; x++)
+       {
+         if (pIEE[x].ASC > 0)
+           {
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&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;
+               }
+           }
+       }
+
+
+      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]))
+               {
+               case SENSE_IES:
+                 STEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on IES\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      for (x = 0; x < DTE; x++)
+       {
+         if (pDTE[x].ASC > 0)
+           {
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+               {
+               case SENSE_IES:
+                 DTEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Abort on DTE\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      /*
+       * OK, we have an error, do an INIT ELMENT
+       * For the tape if not handled by the robot we have
+       * to do some extra checks
+       */
+      if (error == 1)
+       {
+         if (GenericResetStatus(DeviceFD) != 0)
+           {
+             ElementStatusValid = 0;
+             DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Can't init status\n");
+             return(-1);
+           }
+         error = 0;
+       }
+
+      if (DTEError == 1)
+       {
+         TapeStatus();
+         /*
+          * If the status is empty to an move from tape to tape
+          * This is if the tape is ejected, but not unloaded
+          */
+         if (pDTE[0].status == 'E')
+           {
+             DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "DLT448ElementStatus : try to move tape to tape drive\n");
+             pDev[DeviceFD].functions->function_move(DeviceFD, pDTE[0].address, pDTE[0].address);
+           }
+       }
+         /* Done GetElementStatus */
+    }
+
+  if (error != 0)
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "DLT448ElementStatus : Can't init status (after loop)\n");
+      return(-1);
+    }
+
+  ElementStatusValid = 1;
+  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "#### STOP DLT448ElementStatus\n");
+  return(0);
+}
+
+
+/* 
+ * Much the same like GenericElementStatus but
+ * 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 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 :-) */
+  int loop = 2;    /* Redo it if an error has been reset */
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT, "##### START SDXElementStatus\n");
+
+  if (pEAAPage == NULL)
+    {
+      /*
+       * If this pointer is null
+       * then try to read the parameter with MODE SENSE
+       *
+       */
+      if (pModePage == NULL && LibModeSenseValid == 0)
+        {
+          if ((pModePage = malloc(0xff)) == NULL)
+            {
+              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"SDXElementStatus : malloc failed\n");
+              return(-1);
+            }
+         if (SCSI_ModeSense(DeviceFD, pModePage, 0xff, 0x8, 0x3f) == 0)
+           {
+             LibModeSenseValid = 1;
+             DecodeModeSense(pModePage, 0, "SDXElementStatus :", 0, debug_file);
+           } else {
+             DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"SDXElementStatus : failed SCSI_ModeSense\n");
+             LibModeSenseValid = -1;
+           }
+        }
+    }
+
+  if (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]))
+               {
+               case SENSE_IES:
+                 MTEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on MTE\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      for (x = 0; x < IEE; x++)
+       {
+         if (pIEE[x].ASC > 0)
+           {
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pIEE[x].ASC, pIEE[x].ASCQ, (char *)&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;
+               }
+           }
+       }
+
+
+      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]))
+               {
+               case SENSE_IES:
+                 STEError = 1;
+                 error = 1;
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on IES\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      for (x = 0; x < DTE; x++)
+       {
+         if (pDTE[x].ASC > 0)
+           {
+             switch(SenseHandler(DeviceFD, 0, SENSE_CHG_ELEMENT_STATUS, pDTE[x].ASC, pDTE[x].ASCQ, (char *)&pDTE[x]))
+               {
+               case SENSE_IES:
+                 DTEError = 1;
+                 /*
+                 error = 1;
+                 */
+                 break;
+               case SENSE_ABORT:
+                 DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Abort on DTE\n");
+                 return(-1);
+                 break;
+               }
+           }
+       }
+
+      /*
+       * OK, we have an error, do an INIT ELMENT
+       * For the tape if not handled by the robot we have
+       * to do some extra checks
+       */
+      if (error == 1)
+       {
+         if (GenericResetStatus(DeviceFD) != 0)
+           {
+             ElementStatusValid = 0;
+             DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Can't init status\n");
+             return(-1);
+           }
+       }
+
+      /* Done GetElementStatus */
+    }
+
+  if (error != 0)
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "SDXElementStatus : Can't init status\n");
+      return(-1);
+    }
+
+  ElementStatusValid = 1;
+  TapeStatus();
+  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT, "#### STOP SDXElementStatus\n");
+  return(0);
+}
+
+
+/*
+ * Reads the element information from the library. There are 2 ways to do this.
+ * Either check the result from the mode sense page to see which types of elements
+ * are available (STE/DTE/MTE....), or do an read element status with the option give
+ * me all and than check what is available.
+ *
+ * Only do the read, error handling is done by the calling function
+ *
+ * Return Values:
+ * < 0   -> Error 
+ * == 0  -> OK
+ *
+ * TODO:
+ */
+int GetElementStatus(int DeviceFD)
+{
+  unsigned char *DataBuffer = NULL;
+  int 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;
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"##### START GetElementStatus\n");
+  
+  barcode = BarCode(DeviceFD);
+
+  /* 
+   * If the MODE_SENSE was successfull we use this Information to read the Elelement Info 
+   */
+  if (pEAAPage != NULL)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Reading Element Status with the info from mode sense\n");
+      /* First the Medim Transport*/
+      if (V2(pEAAPage->NoMediumTransportElements)  > 0)
+        {
+          MTE = V2(pEAAPage->NoMediumTransportElements) ;
+          if (pMTE == NULL)
+            {
+              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);
+         
+          if (SCSI_ReadElementStatus(DeviceFD, 
+                                     CHANGER, 
+                                     0,
+                                     barcode,
+                                     V2(pEAAPage->MediumTransportElementAddress),
+                                     MTE+1,
+                                    sizeof(MediumTransportElementDescriptor_T),
+                                     (char **)&DataBuffer) != 0)
+            {
+              if (DataBuffer != 0)
+               {
+                 free(DataBuffer);
+               }
+              ChgExit("genericElementStatus","Can't read MTE status", FATAL);
+            }
+          ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = sizeof(ElementStatusData_T);
+          
+          ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
+          offset = offset + sizeof(ElementStatusPage_T);
+         length = V2(ElementStatusPage->length);
+          DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"MTE Length %d(%d)\n",length,sizeof(MediumTransportElementDescriptor_T));
+          
+          for (x = 0; x < MTE; x++)
+            {
+              MediumTransportElementDescriptor = (MediumTransportElementDescriptor_T *)&DataBuffer[offset];
+             
+              if (ElementStatusPage->pvoltag == 1)
+                {
+                  strncpy(pMTE[x].VolTag, 
+                          MediumTransportElementDescriptor->pvoltag,
+                          TAG_SIZE);
+                  TerminateString(pMTE[x].VolTag, TAG_SIZE+1);
+                }
+             
+              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 (length >= 5)
+               {
+                 pMTE[x].ASC = MediumTransportElementDescriptor->asc;
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC MTE\n");
+               }
+             
+             if (length >= 6)
+               {
+                 pMTE[x].ASCQ = MediumTransportElementDescriptor->ascq;
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ MTE\n");
+               }
+             
+             if (length >= 0xa)
+               {
+                 if (MediumTransportElementDescriptor->svalid == 1)
+                   {
+                     pMTE[x].from = V2(MediumTransportElementDescriptor->source);
+                   } else {
+                     pMTE[x].from = -1;
+                   }
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source MTE\n");
+               }
+             offset = offset + length; 
+            }
+        }
+      /* 
+       * Storage Elements 
+       */
+      if ( V2(pEAAPage->NoStorageElements)  > 0)
+        {
+          STE = V2(pEAAPage->NoStorageElements);
+          if (pSTE == NULL)
+            {
+              if ((pSTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * STE)) == NULL)
+                {
+                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
+                  return(-1);
+                }
+            }
+          memset(pSTE, 0, sizeof(ElementInfo_T) * STE);
+          
+          if (SCSI_ReadElementStatus(DeviceFD, 
+                                     STORAGE, 
+                                     0,
+                                     barcode,
+                                     V2(pEAAPage->FirstStorageElementAddress),
+                                     STE,
+                                    sizeof(StorageElementDescriptor_T),
+                                     (char **)&DataBuffer) != 0)
+            {
+              if (DataBuffer != 0)
+               {
+                 free(DataBuffer);
+               }
+              ChgExit("GetElementStatus", "Can't read STE status", FATAL);
+            }
+          
+          ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = sizeof(ElementStatusData_T);
+          
+          ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
+          offset = offset + sizeof(ElementStatusPage_T);
+         length = V2(ElementStatusPage->length);
+          DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"STE Length %d\n",length);
+          
+          for (x = 0; x < STE; x++)
+            {
+              StorageElementDescriptor = (StorageElementDescriptor_T *)&DataBuffer[offset];
+              if (ElementStatusPage->pvoltag == 1)
+                {
+                  strncpy(pSTE[x].VolTag, 
+                          StorageElementDescriptor->pvoltag,
+                          TAG_SIZE);
+                  TerminateString(pSTE[x].VolTag, TAG_SIZE+1);
+                }
+              
+              
+              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 (length >= 5)
+               {
+                 pSTE[x].ASC = StorageElementDescriptor->asc;
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC STE\n");
+               }
+             
+             if (length >= 6)
+               {
+                 pSTE[x].ASCQ = StorageElementDescriptor->ascq;
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ STE\n");
+               }
+              
+             if (length >= 0xa)
+               {
+                 if (StorageElementDescriptor->svalid == 1)
+                   {
+                     pSTE[x].from = V2(StorageElementDescriptor->source);
+                   } else {
+                     pSTE[x].from = -1;
+                   }              
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source STE\n");
+               }
+             
+              offset = offset + length; 
+            }
+          
+        }
+      /* 
+       * Import/Export Elements
+       */
+      if ( V2(pEAAPage->NoImportExportElements) > 0)
+        {
+          IEE = V2(pEAAPage->NoImportExportElements);
+          if (pIEE == NULL)
+            {
+              if ((pIEE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * IEE)) == NULL)
+                {
+                  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
+                  return(-1);
+                }
+            }
+          memset(pIEE, 0, sizeof(ElementInfo_T) * IEE);
+          if (SCSI_ReadElementStatus(DeviceFD, 
+                                     IMPORT, 
+                                     0,
+                                     barcode,
+                                     V2(pEAAPage->FirstImportExportElementAddress),
+                                     IEE,
+                                    sizeof(ImportExportElementDescriptor_T),
+                                     (char **)&DataBuffer) != 0)
+            {
+              if (DataBuffer != 0)
+               {
+                 free(DataBuffer);
+               }
+              ChgExit("GetElementStatus", "Can't read IEE status", FATAL);
+            }
+          
+          ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = sizeof(ElementStatusData_T);
+          
+          ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
+          offset = offset + sizeof(ElementStatusPage_T);
+         length = V2(ElementStatusPage->length);
+          DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"IEE Length %d\n",length);
+          
+          for (x = 0; x < IEE; x++)
+            {
+              ImportExportElementDescriptor = (ImportExportElementDescriptor_T *)&DataBuffer[offset];
+              if (ElementStatusPage->pvoltag == 1)
+                {
+                  strncpy(pIEE[x].VolTag, 
+                          ImportExportElementDescriptor->pvoltag,
+                          TAG_SIZE);
+                  TerminateString(pIEE[x].VolTag, TAG_SIZE+1);
+                }
+              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 (length >= 5)
+               {
+                 pIEE[x].ASC = ImportExportElementDescriptor->asc;
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC IEE\n");
+               }
+             
+             if (length >= 6)
+               {
+                 pIEE[x].ASCQ = ImportExportElementDescriptor->ascq;
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ IEE\n");
+               }
+              
+             if (length >= 0xa)
+               {
+                 if (ImportExportElementDescriptor->svalid == 1)
+                   {
+                     pIEE[x].from = V2(ImportExportElementDescriptor->source);
+                   } else {
+                     pIEE[x].from = -1;
+                   }              
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source IEE\n");
+               }
+             
+              offset = offset + length; 
+            }
+          
+        }
+      /* 
+       * Data Transfer Elements
+       */
+      if (V2(pEAAPage->NoDataTransferElements) >0)
+        {
+          DTE = V2(pEAAPage->NoDataTransferElements) ;
+          if (pDTE == NULL)
+            {
+              if ((pDTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * DTE)) == NULL)
+                {
+                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
+                  return(-1);
+                }
+            }
+          memset(pDTE, 0, sizeof(ElementInfo_T) * DTE);
+          if (SCSI_ReadElementStatus(DeviceFD, 
+                                     TAPETYPE, 
+                                     0,
+                                     barcode,
+                                     V2(pEAAPage->FirstDataTransferElementAddress),
+                                     DTE,
+                                    sizeof(DataTransferElementDescriptor_T),
+                                     (char **)&DataBuffer) != 0)
+            {
+              if (DataBuffer != 0)
+               {
+                 free(DataBuffer);
+               }
+              ChgExit("GenericElementStatus", "Can't read DTE status", FATAL);
+            }
+          
+          ElementStatusData = (ElementStatusData_T *)DataBuffer;
+          offset = sizeof(ElementStatusData_T);
+          
+          ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
+          offset = offset + sizeof(ElementStatusPage_T);
+         length = V2(ElementStatusPage->length);
+          DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"DTE Length %d\n",length);
+         
+          for (x = 0; x < DTE; x++)
+            {
+              DataTransferElementDescriptor = (DataTransferElementDescriptor_T *)&DataBuffer[offset];
+              if (ElementStatusPage->pvoltag == 1)
+                {
+                  strncpy(pDTE[x].VolTag, 
+                          DataTransferElementDescriptor->pvoltag,
+                          TAG_SIZE);
+                  TerminateString(pDTE[x].VolTag, TAG_SIZE+1);
+                }
+              pDTE[x].type = ElementStatusPage->type;
+             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 (length >= 5)
+             {
+               pDTE[x].ASC = DataTransferElementDescriptor->asc;
+             } else {
+               DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC DTE\n");
+             }
+             
+             if (length >= 6)
+               {
+                 pDTE[x].ASCQ = DataTransferElementDescriptor->ascq;
+             } else {
+               DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ DTE\n");
+             }
+             
+             if (length >= 0xa)
+               {
+                 if (DataTransferElementDescriptor->svalid == 1)
+                   {
+                     pDTE[x].from = V2(DataTransferElementDescriptor->source);
+                   } else {
+                     pDTE[x].from = -1;
+                   }
+               } else {
+                 DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source STE\n");
+               }
+             
+              offset = offset + length; 
+            }
+        }
+    } else {
+      /*
+       * And now the old way, when we get here the read mode sense page has failed ...
+       */
+      DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Reading Element Status the old way .... (max 255 elements)\n");
+      if (SCSI_ReadElementStatus(DeviceFD, 
+                                 0, 
+                                 0,
+                                 barcode,
+                                 0,
+                                 0xff,
+                                0x7f,
+                                 (char **)&DataBuffer) != 0)
+        {
+         if (DataBuffer != 0)
+           {
+             free(DataBuffer);
+           }
+          ChgExit("GenericElementStatus","Can't get ElementStatus", FATAL);
+        }
+      
+      ElementStatusData = (ElementStatusData_T *)DataBuffer;
+      DataBufferLength = V3(ElementStatusData->count);
+      
+      offset = sizeof(ElementStatusData_T);
+      
+      if (DataBufferLength <= 0) 
+        {
+          DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"DataBufferLength %d\n",DataBufferLength);
+          return(1);
+        }
+      
+      while (offset < DataBufferLength) 
+        {
+          ElementStatusPage = (ElementStatusPage_T *)&DataBuffer[offset];
+          NoOfElements = V3(ElementStatusPage->count) / V2(ElementStatusPage->length);
+          offset = offset + sizeof(ElementStatusPage_T);
+         length = V2(ElementStatusPage->length);
+          
+          switch (ElementStatusPage->type)
+            {
+            case CHANGER:
+              MTE = NoOfElements;
+              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);
+              for (x = 0; x < NoOfElements; x++)
+                {                  
+                  MediumTransportElementDescriptor = (MediumTransportElementDescriptor_T *)&DataBuffer[offset];
+                  if (ElementStatusPage->pvoltag == 1)
+                    {
+                      strncpy(pMTE[x].VolTag, 
+                              MediumTransportElementDescriptor->pvoltag,
+                              TAG_SIZE);
+                      TerminateString(pMTE[x].VolTag, TAG_SIZE+1);
+                    }
+                  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 (length >= 5)
+                   {
+                     pMTE[x].ASC = MediumTransportElementDescriptor->asc;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC MTE\n");
+                   }
+                 
+                 if (length >= 6)
+                   {
+                     pMTE[x].ASCQ = MediumTransportElementDescriptor->ascq;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ MTE\n");
+                   }
+                 
+                 if (length >= 0xa)
+                   {
+                     if (MediumTransportElementDescriptor->svalid == 1)
+                       {
+                         pMTE[x].from = V2(MediumTransportElementDescriptor->source);
+                       } else {
+                         pMTE[x].from = -1;
+                       }                  
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source MTE\n");
+                   }
+
+                 offset = offset + length; 
+               }
+              break;
+            case STORAGE:
+              STE = NoOfElements;
+              if ((pSTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * STE)) == NULL)
+                {
+                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
+                  return(-1);
+                }
+              memset(pSTE, 0, sizeof(ElementInfo_T) * STE);
+              for (x = 0; x < NoOfElements; x++)
+                {
+                 StorageElementDescriptor = (StorageElementDescriptor_T *)&DataBuffer[offset];
+                  if (ElementStatusPage->pvoltag == 1)
+                    {
+                      strncpy(pSTE[x].VolTag, 
+                              StorageElementDescriptor->pvoltag,
+                              TAG_SIZE);
+                      TerminateString(pSTE[x].VolTag, TAG_SIZE+1);
+                    }
+                  
+                  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 (length >= 5)
+                   {
+                     pSTE[x].ASC = StorageElementDescriptor->asc;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC STE\n");
+                   }
+                 
+                 if (length >= 6)
+                   {
+                     pSTE[x].ASCQ = StorageElementDescriptor->ascq;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ STE\n");
+                   }
+                 
+                 if (length >= 0xa)
+                   {
+                     if (StorageElementDescriptor->svalid == 1)
+                       {
+                         pSTE[x].from = V2(StorageElementDescriptor->source);
+                       } else {
+                         pSTE[x].from = -1;
+                       }              
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source STE\n");
+                   }
+                 
+                  offset = offset + length; 
+                }
+              break;
+            case IMPORT:
+              IEE = NoOfElements;
+              if ((pIEE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * IEE)) == NULL)
+                {
+                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
+                  return(-1);
+                }
+              memset(pIEE, 0, sizeof(ElementInfo_T) * IEE);
+              
+              for (x = 0; x < NoOfElements; x++)
+                {
+                  ImportExportElementDescriptor = (ImportExportElementDescriptor_T *)&DataBuffer[offset];
+                  if (ElementStatusPage->pvoltag == 1)
+                    {
+                      strncpy(pIEE[x].VolTag, 
+                              ImportExportElementDescriptor->pvoltag,
+                              TAG_SIZE);
+                      TerminateString(pIEE[x].VolTag, TAG_SIZE+1);
+                    }
+                  ImportExportElementDescriptor = (ImportExportElementDescriptor_T *)&DataBuffer[offset];
+                  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 (length >= 5)
+                   {
+                     pIEE[x].ASC = ImportExportElementDescriptor->asc;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC IEE\n");
+                   }
+                 
+                 if (length >= 6)
+                   {
+                     pIEE[x].ASCQ = ImportExportElementDescriptor->ascq;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ IEE\n");
+                   }
+                 
+                 if (length >= 0xa)
+                   {
+                     if (ImportExportElementDescriptor->svalid == 1)
+                       {
+                         pIEE[x].from = V2(ImportExportElementDescriptor->source);
+                       } else {
+                         pIEE[x].from = -1;
+                       }              
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source IEE\n");
+                   }
+                 
+                 offset = offset + length; 
+               }
+             break;
+            case TAPETYPE:
+              DTE = NoOfElements;
+              if ((pDTE = (ElementInfo_T *)malloc(sizeof(ElementInfo_T) * DTE)) == NULL)
+                {
+                  DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GenericElementStatus : malloc failed\n");
+                  return(-1);
+                }
+              memset(pDTE, 0, sizeof(ElementInfo_T) * DTE);
+             
+              for (x = 0; x < NoOfElements; x++)
+                {
+                 DataTransferElementDescriptor = (DataTransferElementDescriptor_T *)&DataBuffer[offset];
+                  if (ElementStatusPage->pvoltag == 1)
+                    {
+                      strncpy(pSTE[x].VolTag, 
+                              DataTransferElementDescriptor->pvoltag,
+                              TAG_SIZE);
+                      TerminateString(pSTE[x].VolTag, TAG_SIZE+1);
+                    }
+                  pDTE[x].type = ElementStatusPage->type;
+                  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 (length >= 5)
+                   {
+                     pDTE[x].ASC = DataTransferElementDescriptor->asc;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASC DTE\n");
+                   }
+                 
+                 if (length >= 6)
+                   {
+                     pDTE[x].ASCQ = DataTransferElementDescriptor->ascq;
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip ASCQ DTE\n");
+                   }
+                 
+                 if (length >= 0xa)
+                   {
+                     if (DataTransferElementDescriptor->svalid == 1)
+                       {
+                         pDTE[x].from = V2(DataTransferElementDescriptor->source);
+                       } else {
+                         pDTE[x].from = -1;
+                       }
+                   } else {
+                     DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"Skip source STE\n");
+                   }
+                 
+                 offset = offset + length; 
+                }
+              break;
+            default:
+              offset = offset + length; 
+              DebugPrint(DEBUG_ERROR, SECTION_ELEMENT,"GetElementStatus : UnGknown Type %d\n",ElementStatusPage->type);
+              break;
+            }
+        }
+    }
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\n\n\tMedia Transport Elements (robot arms) :\n");
+
+  for ( x = 0; x < MTE; x++)
+    DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\t\tElement #%04d %c\n\t\t\tEXCEPT = %02x\n\t\t\tASC = %02X ASCQ = %02X\n\t\t\tType %d From = %04d\n\t\t\tTAG = %s\n",
+              pMTE[x].address, pMTE[x].status, pMTE[x].except, pMTE[x].ASC,
+              pMTE[x].ASCQ, pMTE[x].type, pMTE[x].from, pMTE[x].VolTag);
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\n\n\tStorage Elements (Media slots) :\n");
+
+  for ( x = 0; x < STE; x++)
+    DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\t\tElement #%04d %c\n\t\t\tEXCEPT = %02X\n\t\t\tASC = %02X ASCQ = %02X\n\t\t\tType %d From = %04d\n\t\t\tTAG = %s\n",
+              pSTE[x].address, pSTE[x].status, pSTE[x].except, pSTE[x].ASC,
+              pSTE[x].ASCQ, pSTE[x].type, pSTE[x].from, pSTE[x].VolTag);
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\n\n\tData Transfer Elements (tape drives) :\n");
+  for ( x = 0; x < DTE; x++)
+    DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\t\tElement #%04d %c\n\t\t\tEXCEPT = %02X\n\t\t\tASC = %02X ASCQ = %02X\n\t\t\tType %d From = %04d\n\t\t\tTAG = %s\n\t\t\tSCSI ADDRESS = %d\n",
+              pDTE[x].address, pDTE[x].status, pDTE[x].except, pDTE[x].ASC,
+              pDTE[x].ASCQ, pDTE[x].type, pDTE[x].from, pDTE[x].VolTag,pDTE[x].scsi);
+
+  DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\n\n\tImport/Export Elements  :\n");
+
+  for ( x = 0; x < IEE; x++)
+    DebugPrint(DEBUG_INFO, SECTION_ELEMENT,"\t\tElement #%04d %c\n\t\t\tEXCEPT = %02X\n\t\t\t\tASC = %02X ASCQ = %02X\n\t\t\tType %d From = %04d\n\t\t\tTAG = %s\n",
+              pIEE[x].address, pIEE[x].status, pIEE[x].except, pIEE[x].ASC,
+              pIEE[x].ASCQ, pIEE[x].type, pIEE[x].from, pIEE[x].VolTag);
+
+
+
+  free(DataBuffer);
+  return(0);
+}
+
+/*
+ * Get sense data
+ * If ClearErrorCounters is set the counters will be reset.
+ * Used by GenericClean for example
+ *
+ * TODO
+ */
+int RequestSense(int DeviceFD, ExtendedRequestSense_T *ExtendedRequestSense, int ClearErrorCounters )
+{
+  CDB_T CDB;
+  int ret;
+  
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START RequestSense\n");
+  
+  CDB[0] = SC_COM_REQUEST_SENSE;               /* REQUEST SENSE */                       
+  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;                 /*  */
+  
+  memset(ExtendedRequestSense, 0, sizeof(ExtendedRequestSense_T));
+  
+  ret = SCSI_Run(DeviceFD, Input, CDB, 6,                      
+                (char *) ExtendedRequestSense,
+                sizeof(ExtendedRequestSense_T),  
+                (char *) ExtendedRequestSense, sizeof(ExtendedRequestSense_T));
+  
+  
+  if (ret < 0)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (%d)\n",ret);
+      return(ret);
+    }
+  
+  if ( ret > 0)
+    {
+      DecodeExtSense(ExtendedRequestSense, "RequestSense : ",debug_file);
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (%d)\n", ExtendedRequestSense->SenseKey);
+      return(ExtendedRequestSense->SenseKey);
+    }
+  
+  dump_hex((char *)ExtendedRequestSense , sizeof(ExtendedRequestSense_T) , DEBUG_INFO, SECTION_SCSI);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP RequestSense (0)\n");
+  return(0);
+}
+
+
+/*
+ * Lookup function pointer for device ....
+ */
+
+
+ElementInfo_T *LookupElement(int address)
+{
+  int x;
+
+  dbprintf(("##### START LookupElement\n"));
+
+  if (DTE > 0)
+    {
+      for (x = 0; x < DTE; x++)
+        {
+          if (pDTE[x].address == address)
+         {
+            dbprintf(("##### STOP LookupElement (DTE)\n"));
+            return(&pDTE[x]);
+         }
+        }
+    }
+
+  if (MTE > 0)
+    {
+      for (x = 0; x < MTE; x++)
+        {
+          if (pMTE[x].address == address)
+         {
+            dbprintf(("##### STOP LookupElement (MTE)\n"));
+            return(&pMTE[x]);
+         }
+        }
+    }
+
+  if (STE > 0)
+    {
+      for (x = 0; x < STE; x++)
+        {
+          if (pSTE[x].address == address)
+         {
+            dbprintf(("##### STOP LookupElement (STE)\n"));
+            return(&pSTE[x]);
+         }
+        }
+    }
+
+  if (IEE > 0)
+    {
+      for ( x = 0; x < IEE; x++)
+        {
+          if (pIEE[x].address == address)
+         {
+            dbprintf(("##### STOP LookupElement (IEE)\n"));
+            return(&pIEE[x]);
+         }
+        }
+    }
+  return(NULL);
+}
+/*
+ * Here comes everything what decode the log Pages
+ *
+ * TODO:
+ * Fix the result handling from TestUnitReady
+ *
+ */
+int LogSense(DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  CDB_T CDB;
+  RequestSense_T *pRequestSense;
+  LogSenseHeader_T *LogSenseHeader;
+  LogParameter_T *LogParameter;
+  struct LogPageDecode *p;
+  int found;
+  char *datestamp = NULL;
+  char *label = NULL;
+  char *result = NULL;
+  extern char *tapestatfile;
+  int i;
+  int ParameterCode;
+  unsigned int value;
+  int length;
+  int count;
+  char *buffer;
+  char *logpages;
+  int nologpages;
+  int size = 128;
+
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### START LogSense\n");
+
+  if (tapestatfile != NULL && 
+      (StatFile = fopen(tapestatfile,"a")) != NULL && 
+      pDev[INDEX_TAPECTL].SCSI == 1) 
+    {
+      if ((pRequestSense  = (RequestSense_T *)malloc(sizeof(RequestSense_T))) == NULL)
+        {
+          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
+              return(-1);
+        }
+      
+      if (GenericRewind(INDEX_TAPECTL) < 0) 
+        { 
+          DebugPrint(DEBUG_INFO, SECTION_TAPE,"LogSense : Rewind failed\n");
+          free(pRequestSense);
+          return(0); 
+        } 
+      /*
+       * Try to read the tape label
+       */
+      if (pDev[INDEX_TAPE].inqdone == 1)
+        {
+         if (pDev[INDEX_TAPE].devopen == 1)
+           {
+             SCSI_CloseDevice(INDEX_TAPE);
+           }
+         
+         if ((result = (char *)tape_rdlabel(pDev[INDEX_TAPE].dev, &datestamp, &label)) == NULL)
+           {
+             fprintf(StatFile, "==== %s ==== %s ====\n", datestamp, label);
+           } else {
+             fprintf(StatFile, "%s\n", result);
+           }
+       }
+
+      if ((buffer = (char *)malloc(size)) == NULL)
+        {
+          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
+          return(-1);
+        }
+      memset(buffer, 0, size);
+      /*
+       * Get the known log pages 
+       */
+      
+      CDB[0] = SC_COM_LOG_SENSE;
+      CDB[1] = 0;
+      CDB[2] = 0x40;    /* 0x40 for current values */
+      CDB[3] = 0;
+      CDB[4] = 0;
+      CDB[5] = 0;
+      CDB[6] = 00;
+      MSB2(&CDB[7], size);
+      CDB[9] = 0;
+      
+            if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
+                              buffer,
+                              size, 
+                              (char *)pRequestSense,
+                              sizeof(RequestSense_T)) != 0)
+        {
+          DecodeSense(pRequestSense, "LogSense : ",debug_file);
+          free(buffer);
+          free(pRequestSense);
+          return(0);
+        }
+      
+      LogSenseHeader = (LogSenseHeader_T *)buffer;
+      nologpages = V2(LogSenseHeader->PageLength);
+      if ((logpages = (char *)malloc(nologpages)) == NULL)
+        {
+          DebugPrint(DEBUG_ERROR, SECTION_TAPE,"LogSense : malloc failed\n");
+          return(-1);
+        }
+      
+      memcpy(logpages, buffer + sizeof(LogSenseHeader_T), nologpages);
+      
+      for (count = 0; count < 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[3] = 0;
+          CDB[4] = 0;
+          CDB[5] = 0;
+          CDB[6] = 00;
+          MSB2(&CDB[7], size);
+          CDB[9] = 0;
+      
+          if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
+                                  buffer,
+                                  size, 
+                                  (char *)pRequestSense,
+                                  sizeof(RequestSense_T)) != 0)
+            { 
+              DecodeSense(pRequestSense, "LogSense : ",debug_file);
+              free(buffer);
+              free(pRequestSense);
+              return(0);
+            }
+          LogSenseHeader = (LogSenseHeader_T *)buffer;
+          length = V2(LogSenseHeader->PageLength);
+          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);
+
+          while(p->ident != NULL) {
+            if ((strcmp(pDev[INDEX_TAPECTL].ident, p->ident) == 0 ||strcmp("*", p->ident) == 0)  && p->LogPage == logpages[count]) {
+              p->decode(LogParameter, length);
+              found = 1;
+              fprintf(StatFile, "\n");
+              break;
+            }
+            p++;
+          }
+
+         /*
+         *  Hack to disable the printing of unknown pages
+         */
+         found = 1;
+
+          if (!found) {
+            fprintf(StatFile, "Logpage No %d = %x\n", count ,logpages[count]);
+      
+            while ((char *)LogParameter < (buffer + length)) {
+              i = LogParameter->ParameterLength;
+              ParameterCode = V2(LogParameter->ParameterCode);
+              switch (i) {
+              case 1:
+                value = V1((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));
+                fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
+                break;
+              case 3:
+                value = V3((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));
+                fprintf(StatFile, "ParameterCode %02X = %u(%d)\n", ParameterCode, value, i);
+                break;
+              case 5:
+                value = V5((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);
+            }
+            fprintf(StatFile, "\n");
+          }
+        }
+      }
+
+      /*
+       * Test only !!!!
+       * Reset the cumulative counters 
+       */
+      CDB[0] = SC_COM_LOG_SELECT;
+      CDB[1] = 2;
+      CDB[2] = 0xc0;  
+      CDB[3] = 0;
+      CDB[4] = 0;
+      CDB[5] = 0;
+      CDB[6] = 0;
+      CDB[7] = 0;
+      CDB[8] = 0;
+      CDB[9] = 0;
+      
+            if (SCSI_Run(INDEX_TAPECTL, Input, CDB, 10,
+                              buffer,
+                              size, 
+                              (char *)pRequestSense,
+                              sizeof(RequestSense_T)) != 0)
+        {
+          DecodeSense(pRequestSense, "LogSense : ",debug_file);
+          free(buffer);
+          free(pRequestSense);
+          return(0);
+        }
+
+      free(pRequestSense);
+      free(buffer);
+    }
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"##### STOP LogSense\n");
+  
+  return(0);
+}
+
+void WriteErrorCountersPage(LogParameter_T *buffer, int length)
+{
+  int i;
+  int value;
+  LogParameter_T *LogParameter;
+  int ParameterCode;
+  LogParameter = buffer;
+
+  fprintf(StatFile, "\tWrite Error Counters Page\n");
+
+  while ((char *)LogParameter < ((char *)buffer + length)) {
+    i = LogParameter->ParameterLength;
+    ParameterCode = V2(LogParameter->ParameterCode);
+
+    value = 0;
+    if (Decode(LogParameter, &value) == 0) {
+      switch (ParameterCode) {
+      case 2:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Rewrites",
+                value);
+        break;
+      case 3:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Errors Corrected",
+                value);
+        break;
+      case 4:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Times E. Processed",
+                value);
+        break;
+      case 5:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Bytes Processed",
+                value);
+        break;
+      case 6:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Unrecoverable Errors",
+                value);
+        break;
+      default:
+        fprintf(StatFile, "Unknown ParameterCode %02X = %u(%d)\n", 
+                ParameterCode,
+                value, i);
+        break;
+      }
+    } else {
+      fprintf(StatFile, "Error decoding Result\n");
+    }
+    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+  }
+}
+
+void ReadErrorCountersPage(LogParameter_T *buffer, int length)
+{
+  int i;
+  int value;
+  LogParameter_T *LogParameter;
+  int ParameterCode;
+  LogParameter = buffer;
+
+  fprintf(StatFile, "\tRead Error Counters Page\n");
+
+  while ((char *)LogParameter < ((char *)buffer + length)) {
+    i = LogParameter->ParameterLength;
+    ParameterCode = V2(LogParameter->ParameterCode);
+
+    if (Decode(LogParameter, &value) == 0) {
+      switch (ParameterCode) {
+      case 2:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Rereads",
+                value);
+        break;
+      case 3:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Errors Corrected",
+                value);
+        break;
+      case 4:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Times E. Processed",
+                value);
+        break;
+      case 5:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Bytes Processed",
+                value);
+        break;
+      case 6:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Unrecoverable Errors",
+                value);
+        break;
+      default:
+        fprintf(StatFile, "Unknown ParameterCode %02X = %u(%d)\n", 
+                ParameterCode,
+                value, i);
+        break;
+      }
+    } else {
+      fprintf(StatFile, "Error decoding Result\n");
+    }
+    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+  }
+}
+
+void C1553APage30(LogParameter_T *buffer, int length)
+{
+  int i;
+  int value;
+  LogParameter_T *LogParameter;
+  int ParameterCode;
+  LogParameter = buffer;
+
+  fprintf(StatFile, "\tData compression transfer Page\n");
+
+  while ((char *)LogParameter < ((char *)buffer + length)) {
+    i = LogParameter->ParameterLength;
+    ParameterCode = V2(LogParameter->ParameterCode);
+
+    if (Decode(LogParameter, &value) == 0) {
+      switch (ParameterCode) {
+      default:
+        fprintf(StatFile, "Unknown ParameterCode %02X = %u(%d)\n", 
+                ParameterCode,
+                value, i);
+        break;
+      }
+    }
+    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+  }
+}
+
+void C1553APage37(LogParameter_T *buffer, int length)
+{
+  int i;
+  int value;
+  LogParameter_T *LogParameter;
+  int ParameterCode;
+  LogParameter = buffer;
+
+  fprintf(StatFile, "\tDrive Counters Page\n");
+
+  while ((char *)LogParameter < ((char *)buffer + length)) {
+    i = LogParameter->ParameterLength;
+    ParameterCode = V2(LogParameter->ParameterCode);
+
+    if (Decode(LogParameter, &value) == 0) {
+      switch (ParameterCode) {
+      case 1:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total loads",
+                value);
+        break;
+      case 2:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total write drive errors",
+                value);
+        break;
+      case 3:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total read drive errors",
+                value);
+        break;
+      default:
+        fprintf(StatFile, "Unknown ParameterCode %02X = %u(%d)\n", 
+                ParameterCode,
+                value, i);
+        break;
+      }
+    }
+    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i);
+  }
+}
+
+void EXB85058HEPage39(LogParameter_T *buffer, int length)
+{
+  int i;
+  int value;
+  LogParameter_T *LogParameter;
+  int ParameterCode;
+  LogParameter = buffer;
+
+  fprintf(StatFile, "\tData Compression Page\n");
+
+  while ((char *)LogParameter < ((char *)buffer + length)) {
+    i = LogParameter->ParameterLength;
+    ParameterCode = V2(LogParameter->ParameterCode);
+
+    if (Decode(LogParameter, &value) == 0) {
+      switch (ParameterCode) {
+      case 5:
+        fprintf(StatFile, "%-30s = %u\n",
+                "KB to Compressor",
+                value);
+        break;
+      case 7:
+        fprintf(StatFile, "%-30s = %u\n",
+                "KB to tape",
+                value);
+        break;
+      default:
+        fprintf(StatFile, "Unknown ParameterCode %02X = %u(%d)\n", 
+                ParameterCode,
+                value, i);
+        break;
+      }
+    }
+    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i); 
+  }
+}
+
+void EXB85058HEPage3c(LogParameter_T *buffer, int length)
+{
+  int i;
+  int value;
+  LogParameter_T *LogParameter;
+  int ParameterCode;
+  LogParameter = buffer;
+
+  fprintf(StatFile, "\tDrive Usage Information Page\n");
+
+  while ((char *)LogParameter < ((char *)buffer + length)) {
+    i = LogParameter->ParameterLength;
+    ParameterCode = V2(LogParameter->ParameterCode);
+
+    if (Decode(LogParameter, &value) == 0) {
+      switch (ParameterCode) {
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+        break;
+      case 6:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Total Load Count",
+                value);
+        break;
+      case 7:
+        fprintf(StatFile, "%-30s = %u\n",
+                "MinutesSince Last Clean",
+                value);
+        break;
+      case 8:
+      case 9:
+        break;
+      case 0xa:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Cleaning Count",
+                value);
+        break;
+      case 0xb:
+      case 0xc:
+      case 0xd:
+      case 0xe:
+      case 0xf:
+      case 0x10:
+        break;
+      case 0x11:
+        fprintf(StatFile, "%-30s = %u\n",
+                "Time to clean",
+                value);
+        break;
+      case 0x12:
+      case 0x13:
+      case 0x14:
+        break;
+      default:
+        fprintf(StatFile, "Unknown ParameterCode %02X = %u(%d)\n", 
+                ParameterCode,
+                value, i);
+        break;
+      }
+    }
+    LogParameter = (LogParameter_T *)((char *)LogParameter +  sizeof(LogParameter_T) + i); 
+  }
+}
+
+int Decode(LogParameter_T *LogParameter, int *value)
+{
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START Decode\n");
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"Decode Parameter with length %d\n", LogParameter->ParameterLength);
+  switch (LogParameter->ParameterLength) {
+  case 1:
+    *value = V1((char *)LogParameter + sizeof(LogParameter_T));
+    break;
+  case 2:
+    *value = V2((char *)LogParameter + sizeof(LogParameter_T));
+    break;
+  case 3:
+    *value = V3((char *)LogParameter + sizeof(LogParameter_T));
+    break;
+  case 4:
+    *value = V4((char *)LogParameter + sizeof(LogParameter_T));
+    break;
+  case 5:
+    *value = V5((char *)LogParameter + sizeof(LogParameter_T));
+    break;
+  case 6:
+    *value = V6((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);
+  }
+  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)
+{
+       if (p != NULL)
+       {
+               printf("%s Devicefd   %d\n", device, p->fd);
+               printf("%s Can SCSI   %d\n", device, p->SCSI);
+               printf("%s Device     %s\n", device, (p->dev != NULL)? p->dev:"No set");
+               printf("%s ConfigName %s\n", device, (p->ConfigName != NULL) ? p->ConfigName:"Not ser");
+       } else {
+               printf("%s Null Pointer ....\n", device);
+       }
+       printf("\n");
+}
+
+void ChangerReplay(char *option)
+{
+    char buffer[1024];
+    FILE *ip;
+    int x = 0, bufferx;
+   
+    if ((ip=fopen("/tmp/chg-scsi-trace", "r")) == NULL)
+      {
+       exit(1);
+      }
+    
+    while (fscanf(ip, "%2x", &bufferx) != EOF)
+      {
+       buffer[x] = bufferx;
+       x++;
+      }
+
+    DecodeModeSense(&buffer[0], 12, "DLT448ElementStatus :", 0, debug_file);
+}
+
+/*
+ * 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)
+{
+  extern OpenFiles_T *pDev;
+  int x;
+  FILE *out;
+  ExtendedRequestSense_T ExtRequestSense;
+  MBC_T *pbarcoderes = malloc(sizeof(MBC_T));
+  
+  ChangerCMD_T *p = (ChangerCMD_T *)&ChangerIO;
+  memset(pbarcoderes, 0, sizeof(MBC_T));
+
+  if ((pModePage = (char *)malloc(0xff)) == NULL)
+    {
+      printf("malloc failed \n");
+      return;
+    }
+
+  if ((out = fdopen(1 , "w")) == NULL)
+    {
+      printf("Error fdopen stdout\n");
+      return;
+    }
+  
+  if (strcmp("types", option) == 0 || strcmp("all", option) == 0)
+  {
+    while(p->ident != NULL)
+      {
+         printf ("Ident = %s, type = %s\n",p->ident, p->type);
+         p++;
+      }
+    DumpSense();
+  }
+
+  if (strcmp("robot", option) == 0 || strcmp("all", option) == 0)
+      {
+        if (ElementStatusValid == 0)
+          {
+            if (pDev[INDEX_CHANGER].functions->function_status(pDev[INDEX_CHANGER].fd, 1) != 0)
+              {
+                printf("Can not initialize changer status\n");
+                return;
+              }
+          }
+        /*      0123456789012345678901234567890123456789012 */
+       if (HasBarCode)
+       {
+               printf("Address Type Status From Barcode Label\n");
+       } else {
+               printf("Address Type Status From\n");
+       }
+        printf("-------------------------------------------\n");
+        
+        
+        for ( x = 0; x < MTE; x++)
+       if (HasBarCode)
+       {
+          printf("%07d MTE  %s  %04d %s ",pMTE[x].address,
+                 (pMTE[x].full ? "Full " :"Empty"),
+                 pMTE[x].from, pMTE[x].VolTag);
+
+         if (pMTE[x].full == 1)
+           {
+             pbarcoderes->action = BARCODE_BARCODE;
+             strcpy(pbarcoderes->data.barcode, pMTE[x].VolTag);
+             
+             if (MapBarCode(labelfile, pbarcoderes) == 0 )
+               { 
+                 printf("No mapping\n");
+               } else {
+                 printf("%s \n",pbarcoderes->data.voltag);
+               }
+           } else {
+             printf("\n");
+           }
+       } else {
+          printf("%07d MTE  %s  %04d \n",pMTE[x].address,
+                 (pMTE[x].full ? "Full " :"Empty"),
+                 pMTE[x].from);
+       }
+        
+        
+        for ( x = 0; x < STE; x++)
+       if (HasBarCode)
+       {
+          printf("%07d STE  %s  %04d %s ",pSTE[x].address,  
+                 (pSTE[x].full ? "Full ":"Empty"),
+                 pSTE[x].from, pSTE[x].VolTag);
+
+         if (pSTE[x].full == 1)
+           {
+             pbarcoderes->action = BARCODE_BARCODE;
+             strcpy(pbarcoderes->data.barcode, pSTE[x].VolTag);
+             
+             if (MapBarCode(labelfile, pbarcoderes) == 0 )
+               {
+                 printf("No mapping\n");
+               } else {
+                 printf("%s \n",pbarcoderes->data.voltag);
+               }
+           } else {
+             printf("\n");
+           }
+       } else {
+          printf("%07d STE  %s  %04d %s\n",pSTE[x].address,  
+                 (pSTE[x].full ? "Full ":"Empty"),
+                 pSTE[x].from, pSTE[x].VolTag);
+       }
+        
+        
+        for ( x = 0; x < DTE; x++)
+       if (HasBarCode)
+       {
+          printf("%07d DTE  %s  %04d %s ",pDTE[x].address,  
+                 (pDTE[x].full ? "Full " : "Empty"),
+                 pDTE[x].from, pDTE[x].VolTag);
+
+         if (pDTE[x].full == 1)
+           {
+             pbarcoderes->action = BARCODE_BARCODE;
+             strcpy(pbarcoderes->data.barcode, pDTE[x].VolTag);
+             
+             if (MapBarCode(labelfile, pbarcoderes) == 0 )
+               {
+                 printf("No mapping\n");
+               } else {
+                 printf("%s \n",pbarcoderes->data.voltag);
+               }
+           } else {
+             printf("\n");
+           }
+
+       } else {
+          printf("%07d DTE  %s  %04d %s\n",pDTE[x].address,  
+                 (pDTE[x].full ? "Full " : "Empty"),
+                 pDTE[x].from, pDTE[x].VolTag);
+       }
+        
+        for ( x = 0; x < IEE; x++)
+       if (HasBarCode)
+       {       
+          printf("%07d IEE  %s  %04d %s ",pIEE[x].address,  
+                 (pIEE[x].full ? "Full " : "Empty"),
+                 pIEE[x].from, pIEE[x].VolTag);
+
+         if (pIEE[x].full == 1)
+           {
+             pbarcoderes->action = BARCODE_BARCODE;
+             strcpy(pbarcoderes->data.barcode, pIEE[x].VolTag);
+             
+             if (MapBarCode(labelfile, pbarcoderes) == 0 )
+               {
+                 printf("No mapping\n");
+               } else {
+                 printf("%s \n",pbarcoderes->data.voltag);
+               }
+           } else {
+             printf("\n");
+           }
+
+       } else {
+          printf("%07d IEE  %s  %04d %s\n",pIEE[x].address,  
+                 (pIEE[x].full ? "Full " : "Empty"),
+                 pIEE[x].from, pIEE[x].VolTag);
+       }
+        
+      }
+
+  if (strcmp("sense", option) == 0 || strcmp("all", option) == 0)
+    {
+      if (pDev[INDEX_CHANGER].SCSI == 1)
+       {
+           printf("\nSense Status from robot:\n");
+           RequestSense(INDEX_CHANGER , &ExtRequestSense, 0);
+           DecodeExtSense(&ExtRequestSense, "", out);
+       }
+      
+      if (pDev[INDEX_TAPE].SCSI == 1)
+        {
+          printf("\n");
+          printf("Sense Status from tape (tapectl):\n");
+          RequestSense(INDEX_TAPE, &ExtRequestSense, 0); 
+          DecodeExtSense(&ExtRequestSense, "", out);
+        }
+
+      if (pDev[INDEX_TAPECTL].SCSI == 1)
+        {
+          printf("\n");
+          printf("Sense Status from tape (tapectl):\n");
+          RequestSense(INDEX_TAPECTL, &ExtRequestSense, 0); 
+          DecodeExtSense(&ExtRequestSense, "", out);
+        }
+    }
+
+    if (strcmp("ModeSenseRobot", option) == 0 || strcmp("all", option) == 0)
+      {
+        printf("\n");
+        if (SCSI_ModeSense(INDEX_CHANGER, pModePage, 0xff, 0x08, 0x3f) == 0)
+          {
+            DecodeModeSense(pModePage, 0, "Changer :" , 0, out); 
+          }
+      }
+  
+    if (strcmp("ModeSenseTape", option) == 0 || strcmp("all", option) == 0)
+      {
+        if (pDev[INDEX_TAPECTL].SCSI == 1)
+        {
+          printf("\n");
+          if (SCSI_ModeSense(INDEX_TAPECTL, pModePage, 0xff, 0x0, 0x3f) == 0)
+            {
+              DecodeModeSense(pModePage, 0, "Tape :" , 1, out); 
+            }
+        }
+      }
+
+    if (strcmp("fd", option) == 0 || strcmp("all", option) == 0)
+    {
+      printf("changer_dev  %s\n",changer_dev);
+      printf("changer_file %s\n", changer_file);
+      printf("tape_device  %s\n\n", tape_device);
+      DumpDev(&pDev[INDEX_TAPE], "pTapeDev");
+      DumpDev(&pDev[INDEX_TAPECTL], "pTapeDevCtl");
+      DumpDev(&pDev[INDEX_CHANGER], "pChangerDev");
+    }
+
+  if (GenericClean("") == 1)
+    printf("Tape needs cleaning\n");  
+}
+
+void dump_hex(char *p, int size, int level, int section)
+{
+    int row_count = 0;
+    int x = 0;
+
+    while (row_count < size)
+    {
+        DebugPrint(level, section,"%02X ", (unsigned char)p[row_count]);
+        if (((row_count + 1) % 16) == 0 )
+          {
+            dbprintf(("   "));
+            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,".");
+              }
+            DebugPrint(level, section,"\n");
+          }
+       row_count++;
+    }
+    DebugPrint(level, section,"\n");
+}
+
+void TerminateString(char *string, int length)
+{
+  int x;
+  
+  for (x = length; x >= 0 && !isalnum((int)string[x]); x--)
+    string[x] = '\0';
+}
+
+void ChgExit(char *where, char *reason, int level)
+{
+   dbprintf(("ChgExit in %s, reason %s\n", where, reason));
+   fprintf(stderr,"%s\n",reason);
+   exit(2); 
+}
+
+/* OK here starts a new set of functions.
+ * Every function is for one SCSI command.
+ * Prefix is SCSI_ and then the SCSI command name
+*/
+
+/*
+ * SCSI_Run is an wrapper arround SCSI_ExecuteCommand
+ * It seems to be an good idea to check first if the device
+ * 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 ret = 0;
+  int ok = 0;
+  int maxtries = 0;
+  RequestSense_T *pRqS;
+
+  pRqS = (RequestSense_T *)pRequestSense;
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Run TestUnitReady\n");
+  while (!ok && maxtries < MAXTRIES)
+    {
+      ret = SCSI_TestUnitReady(DeviceFD, (RequestSense_T *)pRequestSense );
+      DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Run TestUnitReady ret %d\n",ret);
+      switch (ret)
+       {
+       case SCSI_OK:
+         ok=1;
+         break;
+       case SCSI_SENSE:
+         switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRequestSense))
+           {
+           case SENSE_NO:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_NO\n");
+             ok=1;
+             break;
+           case SENSE_TAPE_NOT_ONLINE:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n");
+             ok=1;
+             break;
+           case SENSE_IGNORE:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_IGNORE\n");
+             ok=1;
+             break;
+           case SENSE_ABORT:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_ABORT\n");
+             return(-1);
+             break;
+           case SENSE_RETRY:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SENSE_RETRY\n");
+             break;
+           default:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) default (SENSE)\n");
+             ok=1;
+             break;
+           }
+         break;
+       case SCSI_ERROR:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_ERROR\n");
+         return(-1);
+         break;     
+       case SCSI_BUSY:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_BUSY\n");
+         break;
+       case SCSI_CHECK:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_CHECK\n");
+         break;
+       default:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) unknown (%d)\n",ret);
+         break;
+       }
+      if (!ok)
+      {
+       sleep(1);
+        maxtries++;
+      }
+    }
+  
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run TestUnitReady after %d sec:\n",maxtries);
+  
+  if (ok != 1)
+    {
+      DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run Exit %d\n",ret);
+      return(-1);
+    }
+
+  ok = 0;
+  maxtries = 0;
+  while (!ok && maxtries < MAXTRIES)
+    {
+      ret = SCSI_ExecuteCommand(DeviceFD,
+                               Direction,
+                               CDB,
+                               CDB_Length,
+                               DataBuffer,
+                               DataBufferLength,
+                               pRequestSense,
+                               RequestSenseLength);
+      
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run Exit %d\n",ret);
+      switch (ret)
+       {
+       case SCSI_OK:
+         ok=1;
+         break;
+       case SCSI_SENSE:
+         switch (SenseHandler(DeviceFD, 0, pRqS->SenseKey, pRqS->AdditionalSenseCode, pRqS->AdditionalSenseCodeQualifier, pRequestSense))
+           {
+           case SENSE_NO:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_NO\n");
+             ok=1;
+             break;
+           case SENSE_TAPE_NOT_ONLINE:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_TAPE_NOT_ONLINE\n");
+             ok=1;
+             break;
+           case SENSE_IGNORE:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_IGNORE\n");
+             ok=1;
+             break;
+           case SENSE_ABORT:
+             DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run SENSE_ABORT\n");
+             return(-1);
+             break;
+           case SENSE_RETRY:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SENSE_RETRY\n");
+             break;
+           default:
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run default (SENSE)\n");
+             ok=1;
+             break;
+           }
+         break;
+       case SCSI_ERROR:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run SCSI_ERROR\n");
+         return(-1);
+         break;
+       case SCSI_BUSY:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run SCSI_BUSY\n");
+         break;
+       case SCSI_CHECK:
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Run (TestUnitReady) SCSI_CHECK\n");
+         break;
+       default:
+         DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_Run (TestUnitReady) unknown (%d)\n",ret);
+         break;
+       }
+      maxtries++;
+      sleep(1);
+    }
+  
+  if (ok == 1)
+    {
+      return(0);
+    } else {
+      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)
+{
+  RequestSense_T *pRequestSense;
+  int retry = 1;
+  CDB_T CDB;
+  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);
+    }
+  
+  while (retry > 0 && retry < MAX_RETRIES)
+    {
+      CDB[0]  = 0xE5;
+      CDB[1]  = 0;
+      MSB2(&CDB[2],AE_MTE);    /* Which MTE to use, default 0 */
+      MSB2(&CDB[4],AE_DTE);    /* Which DTE to use, no range check !! */
+      MSB2(&CDB[6],AE_STE);    /* Which STE to use, no range check !! */
+      CDB[8]  = 0;
+      CDB[9]  = 0;
+      CDB[10] = 0;
+      CDB[11] = 0;
+      
+      ret = SCSI_Run(DeviceFD, Input, CDB, 12,
+                                NULL, 0, (char *)pRequestSense, sizeof(RequestSense_T)); 
+
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SCSI_Run = %d\n", ret);
+      DecodeSense(pRequestSense, "SCSI_AlignElements :",debug_file);
+
+      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]); 
+          DebugPrint(DEBUG_ERROR, SECTION_SCSI,"\n");    
+          return(ret);
+        }
+      if ( ret > 0)
+        {
+          switch(SenseHandler(DeviceFD, 0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+            {
+            case SENSE_IGNORE:
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : SENSE_IGNORE\n");
+              return(0);
+              break;
+            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;
+            case SENSE_TAPE_NOT_UNLOADED:
+              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_AlignElements : Tape still loaded, eject failed\n");
+              return(-1);
+              break;
+            default:
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : end %d\n", pRequestSense->SenseKey);
+              return(pRequestSense->SenseKey);
+              break;
+            }
+        }
+      if (ret == 0)
+        {
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_AlignElements : end %d\n", ret);
+          return(ret);
+        } 
+    }
+  return(ret);
+}
+
+
+int SCSI_Move(int DeviceFD, unsigned char chm, int from, int to)
+{
+  RequestSense_T *pRequestSense;
+  int retry = 1;
+  CDB_T CDB;
+  int ret;
+  int i;
+
+  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);
+    }
+
+  while (retry > 0 && retry < MAX_RETRIES)
+    {
+      CDB[0]  = SC_MOVE_MEDIUM;
+      CDB[1]  = 0;
+      CDB[2]  = 0;
+      CDB[3]  = chm;     /* Address of CHM */
+      MSB2(&CDB[4],from);
+      MSB2(&CDB[6],to);
+      CDB[8]  = 0;
+      CDB[9]  = 0;
+      CDB[10] = 0;
+      CDB[11] = 0;
+      
+      ret = SCSI_Run(DeviceFD, Input, CDB, 12,
+                                NULL, 0, (char *)pRequestSense, sizeof(RequestSense_T)); 
+
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Move : SCSI_Run = %d\n", ret);
+      DecodeSense(pRequestSense, "SCSI_Move :",debug_file);
+
+      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]); 
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"\n");    
+          return(ret);
+        }
+      if ( ret > 0)
+        {
+          switch(SenseHandler(DeviceFD,  0 , pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+            {
+            case SENSE_IGNORE:
+              dbprintf(("SCSI_Move : SENSE_IGNORE\n"));
+              return(0);
+              break;
+            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;
+            case SENSE_TAPE_NOT_UNLOADED:
+              dbprintf(("SCSI_Move : Tape still loaded, eject failed\n"));
+              return(-1);
+              break;
+            default:
+              dbprintf(("SCSI_Move : end %d\n", pRequestSense->SenseKey));
+              return(pRequestSense->SenseKey);
+              break;
+            }
+        }
+      if (ret == 0)
+        {
+          dbprintf(("SCSI_Move : end %d\n", ret));
+          return(ret);
+        } 
+    }
+  return(ret);
+}
+
+int SCSI_LoadUnload(int DeviceFD, RequestSense_T *pRequestSense, unsigned char byte1, unsigned char load)
+{
+  CDB_T CDB;
+  int ret;
+
+  dbprintf(("##### START SCSI_LoadUnload\n"));
+  
+  CDB[0] = SC_COM_UNLOAD;
+  CDB[1] = byte1;             
+  CDB[2] = 0;
+  CDB[3] = 0;
+  CDB[4] = load;
+  CDB[5] = 0;
+  
+  ret = SCSI_Run(DeviceFD, Input, CDB, 6,
+                            NULL, 0, 
+                            (char *) pRequestSense,
+                            sizeof(RequestSense_T));
+    
+  if (ret < 0)
+    {
+      dbprintf(("SCSI_Unload : failed %d\n", ret));
+      return(-1);
+    } 
+
+  return(ret);
+}
+
+int SCSI_TestUnitReady(int DeviceFD, RequestSense_T *pRequestSense)
+{
+  CDB_T CDB;
+  int ret;
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_TestUnitReady\n");
+
+  CDB[0] = SC_COM_TEST_UNIT_READY;
+  CDB[1] = 0;
+  CDB[2] = 0;
+  CDB[3] = 0;
+  CDB[4] = 0;
+  CDB[5] = 0;
+
+  ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 6,
+                      NULL, 0, 
+                      (char *) pRequestSense,
+                      sizeof(RequestSense_T));
+
+  /*
+   * We got an error, so let the calling function handle this 
+   */
+  if (ret > 0)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP SCSI_TestUnitReady (1)\n");
+      return(ret);
+    }
+
+  /*
+   * OK, no error condition
+   * If no sense is set, the Unit is ready
+   */
+  if (pRequestSense->ErrorCode == 0 && pRequestSense->SenseKey == 0)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP SCSI_TestUnitReady (1)\n");
+      return(0);
+    }
+
+  /*
+   * Some sense is set
+   */
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"###### STOP SCSI_TestUnitReady (0)\n");
+  return(SCSI_SENSE);
+}
+
+
+int SCSI_ModeSelect(int DeviceFD, char *buffer, unsigned char length, unsigned char save, unsigned char mode, unsigned char lun)
+{
+  CDB_T CDB;
+  RequestSense_T *pRequestSense;
+  int ret;
+  int retry = 1;
+  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"));
+      return(-1);
+    }
+
+  memset(sendbuf, 0 , length + 4);
+
+  memcpy(&sendbuf[4], buffer, length);
+  dump_hex(sendbuf, length+4, DEBUG_INFO, SECTION_SCSI);
+
+  while (retry > 0 && retry < MAX_RETRIES)
+    {
+      memset(pRequestSense, 0, sizeof(RequestSense_T));
+      
+      CDB[0] = SC_COM_MODE_SELECT;
+      CDB[1] = ((lun << 5) & 0xF0) | ((mode << 4) & 0x10) | (save & 1);
+      CDB[2] = 0;
+      CDB[3] = 0;
+      CDB[4] = length + 4;
+      CDB[5] = 0;
+      ret = SCSI_Run(DeviceFD, Output, CDB, 6,                      
+                                sendbuf,
+                                length + 4, 
+                                (char *) pRequestSense,
+                                sizeof(RequestSense_T));
+      if (ret < 0)
+        {
+          dbprintf(("SCSI_ModeSelect : ret %d\n", ret));
+          return(ret);
+        }
+      
+      if ( ret > 0)
+        {
+          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+            {
+            case SENSE_IGNORE:
+              dbprintf(("SCSI_ModeSelect : SENSE_IGNORE\n"));
+              return(0);
+              break;
+            case SENSE_RETRY:
+              dbprintf(("SCSI_ModeSelect : SENSE_RETRY no %d\n", retry));
+              break;
+            default:
+              dbprintf(("SCSI_ModeSelect : end %d\n", pRequestSense->SenseKey));
+              return(pRequestSense->SenseKey);
+              break;
+            }
+        }
+      retry++;
+      if (ret == 0)
+        {
+          dbprintf(("SCSI_ModeSelect end: %d\n", ret));
+          return(ret);
+        }
+    }
+  dbprintf(("SCSI_ModeSelect end: %d\n", ret));
+  return(ret);
+}
+
+
+
+int SCSI_ModeSense(int DeviceFD, char *buffer, u_char size, u_char byte1, u_char byte2)
+{
+  CDB_T CDB;
+  RequestSense_T *pRequestSense;
+  int ret = 1;
+  int retry = 1;
+
+  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);
+      }
+
+  while (ret && retry < MAX_RETRIES)
+    {
+      memset(pRequestSense, 0, sizeof(RequestSense_T));
+      memset(buffer, 0, size);
+      
+      CDB[0] = SC_COM_MODE_SENSE;
+      CDB[1] = byte1;
+      CDB[2] = byte2;
+      CDB[3] = 0;
+      CDB[4] = size;
+      CDB[5] = 0;
+      ret = SCSI_Run(DeviceFD, Input, CDB, 6,                      
+                                buffer,
+                                size, 
+                                (char *) pRequestSense,
+                                sizeof(RequestSense_T));
+      if (ret < 0)
+        {
+          return(ret);
+        }
+      
+      if ( ret > 0)
+        {
+          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+            {
+            case SENSE_IGNORE:
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
+              return(0);
+              break;
+            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;
+            }
+        }
+      retry++;
+    }
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense end: %d\n", ret);
+  return(ret);
+}
+
+int SCSI_Inquiry(int DeviceFD, SCSIInquiry_T *buffer, u_char size)
+{
+  CDB_T CDB;
+  RequestSense_T *pRequestSense;
+  int i;
+  int ret;
+  int retry = 1;
+
+  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);
+      }
+
+  while (retry > 0 && retry < MAX_RETRIES)
+    {
+      memset(buffer, 0, size);
+      CDB[0] = SC_COM_INQUIRY;
+      CDB[1] = 0;
+      CDB[2] = 0;
+      CDB[3] = 0;
+      CDB[4] = size;
+      CDB[5] = 0;
+      
+      ret = SCSI_ExecuteCommand(DeviceFD, Input, CDB, 6,                      
+                                buffer,
+                                size, 
+                                (char *) 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]);
+          DebugPrint(DEBUG_ERROR, SECTION_SCSI, "\n");   
+      DebugPrint(DEBUG_ERROR, SECTION_SCSI, "Inquiry end: %d\n", ret);
+      return(ret);
+        }
+      if ( ret > 0)
+        {
+          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+            {
+            case SENSE_IGNORE:
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Inquiry : SENSE_IGNORE\n");
+              return(0);
+              break;
+            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;
+            }
+        }
+      retry++;
+      if (ret == 0)
+        {
+          dump_hex((char *)buffer, size, DEBUG_INFO, SECTION_SCSI);
+          DebugPrint(DEBUG_INFO, SECTION_SCSI, "SCSI_Inquiry : end %d\n", ret);
+          return(ret);
+        }
+    }
+  
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_Inquiry end: %d\n", ret);
+  return(ret);
+}
+
+/*
+ * Read the Element Status. If DescriptorSize  != 0 then 
+ * allocate DescriptorSize * NoOfElements for the result from the
+ * Read Element Status command. 
+ * If DescriptorSize == 0 than try to figure out how much space is needed
+ * by 
+ * 1. do an read with an allocation size of 8
+ * 2. from the result take the 'Byte Count of Descriptor Available'
+ * 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)
+{
+  CDB_T CDB;
+  int DataBufferLength;
+  ElementStatusData_T *ElementStatusData;
+  RequestSense_T *pRequestSense;
+  int retry = 1;
+  int ret = -1; 
+  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);
+    }
+  
+  /*
+   * How many elements, if <= 0 than exit with an fatal error
+   */
+  if (NoOfElements <= 0)
+    {
+      ChgExit("SCSI_ReadElementStatus","No of Elements passed are le 0",FATAL);
+    }
+
+  VolTag = (VolTag << 4) & 0x10;
+  type = type & 0xf;
+  lun = (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);
+       }
+      
+      memset(*data, 0, 8);
+      
+      
+      
+      while (retry > 0 && retry < MAX_RETRIES)
+       {
+         memset(pRequestSense, 0, sizeof(RequestSense_T) );
+         
+         CDB[0] = SC_COM_RES;          /* READ ELEMENT STATUS */
+         CDB[1] = 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 */                          
+         MSB3(&CDB[7],8);                   /* Allocation Length */    
+         CDB[10] = 0;                           /* Reserved */                           
+         CDB[11] = 0;                           /* Control */                             
+         
+         ret = SCSI_Run(DeviceFD, Input, CDB, 12,                      
+                        *data, 8, 
+                        (char *)pRequestSense, sizeof(RequestSense_T));
+         
+         
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : (1) SCSI_Run %d\n", ret);
+         if (ret < 0)
+           {
+             DecodeSense(pRequestSense, "SCSI_ReadElementStatus :",debug_file);
+             DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
+             return(ret);
+           }
+         if ( ret > 0)
+           {
+             switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+               {
+               case SENSE_IGNORE:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
+                 retry = 0;
+                 break;
+               case SENSE_RETRY:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_RETRY no %d\n", retry);
+                 sleep(2);
+                 break;
+               default:
+                 DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
+                 return(pRequestSense->SenseKey);
+                 break;
+               }
+           }
+         retry++;
+         if (ret == 0)
+           {
+             retry=0;
+           }
+       }
+      if (retry > 0)
+       {
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
+         return(ret);
+       }
+      ElementStatusData = (ElementStatusData_T *)*data;
+      DataBufferLength = V3(ElementStatusData->count);
+
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus: DataBufferLength %X, ret %d\n",DataBufferLength, ret);
+      
+      dump_hex(*data, 8, DEBUG_INFO, SECTION_ELEMENT);
+    } else { /* DescriptorSize != 0 */
+      DataBufferLength = NoOfElements * DescriptorSize;
+    }
+
+  DataBufferLength = DataBufferLength + 8;
+  *data = realloc(*data, DataBufferLength);
+  memset(*data, 0, DataBufferLength);
+  retry = 1;
+
+  while (retry > 0 && retry < MAX_RETRIES)
+    {
+      memset(pRequestSense, 0, sizeof(RequestSense_T) );
+      
+      CDB[0] = SC_COM_RES;           /* READ ELEMENT STATUS */
+      CDB[1] = 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 */                      
+      MSB3(&CDB[7],DataBufferLength);  /* Allocation Length */    
+      CDB[10] = 0;                                 /* Reserved */                      
+      CDB[11] = 0;                                 /* Control */                       
+      
+      ret = SCSI_Run(DeviceFD, Input, CDB, 12,                      
+                                *data, DataBufferLength, 
+                                (char *)pRequestSense, sizeof(RequestSense_T));
+      
+      
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ReadElementStatus : (2) SCSI_Run %d\n", ret);
+      if (ret < 0)
+        {
+          DecodeSense(pRequestSense, "SCSI_ReadElementStatus :",debug_file);
+         DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
+          return(ret);
+        }
+      if ( ret > 0)
+        {
+          switch(SenseHandler(DeviceFD, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, (char *)pRequestSense))
+            {
+            case SENSE_IGNORE:
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_IGNORE\n");
+              retry = 0;
+              break;
+            case SENSE_RETRY:
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : SENSE_RETRY no %d\n", retry);
+              sleep(2);
+              break;
+            default:
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_ModeSense : end %d\n", pRequestSense->SenseKey);
+              return(pRequestSense->SenseKey);
+              break;
+            }
+        }
+      retry++;
+      if (ret == 0)
+        {
+          retry=0;
+        }
+    }
+
+  if (retry > 0)
+    {
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
+      return(ret);
+    }
+  dump_hex(*data, DataBufferLength, DEBUG_INFO, SECTION_SCSI);
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_ReadElementStatus (%d)\n",ret);
+  return(ret);
+}
+
+printf_arglist_function2(void DebugPrint, int, level, int, section, char *, fmt)
+{
+  va_list argp;
+  char buf[1024];
+  extern changer_t chg;
+  int dlevel,dsection;
+
+  time_t ti;
+
+  time(&ti);
+  if (chg.debuglevel)
+    {
+      sscanf(chg.debuglevel,"%d:%d", &dlevel, &dsection);
+    } else {
+      dlevel=1;
+      dsection=1;
+    }
+
+  arglist_start(argp, fmt);
+  vsnprintf(buf, sizeof(buf), fmt, argp);
+  if (dlevel >= level)
+    {
+      if (section == dsection || dsection == 0)
+       {
+         if (index(buf, '\n') != NULL && strlen(buf) > 1)
+          {
+            dbprintf(("%ld:%s", (long)ti, buf));
+         } else {
+            dbprintf(("%s", buf));
+         }
+       }
+    }
+  arglist_end(argp);  
+
+}
diff --git a/changer-src/scsi-chio.c b/changer-src/scsi-chio.c
new file mode 100644 (file)
index 0000000..8ac7ffa
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ *     $Id: scsi-chio.c,v 1.5.4.8 1999/06/17 18:33:19 th Exp $
+ *
+ *     scsi-chio.c -- library routines to handle the changer
+ *                     support for chio based systems
+ *
+ *     Author: Eric Schnoebelen, eric@cirr.com
+ *     based on work by: Larry Pyeatt,  pyeatt@cs.colostate.edu 
+ *     Copyright: 1997, 1998 Eric Schnoebelen
+ *             
+ */
+
+#include "config.h"
+#include "amanda.h"
+
+#if (defined(HAVE_CHIO_H) || defined(HAVE_SYS_CHIO_H)) \
+    && !defined(HAVE_CAMLIB_H)
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+
+/* This include comes with Gerd Knor's SCSI media changer driver.
+ * If you are porting to another system, this is the file that defines
+ * ioctl calls for the changer.  You will have to track it down yourself
+ * and possibly change all the ioctl() calls in this program.  
+ */
+
+#if defined(HAVE_CHIO_H)
+#  include <chio.h>
+#else /* HAVE_SYS_CHIO_H must be defined */
+#  include <sys/chio.h>
+#endif
+
+char *modname = "@(#)" __FILE__ 
+               ": SCSI support library for the chio(2) interface @(#)";
+
+/*
+ * cache the general changer information, for faster access elsewhere
+ */
+static struct changer_params changer_info;
+static int changer_info_init = 0;
+
+static int get_changer_info(fd)
+{
+int rc = 0;
+
+    if ( !changer_info_init ) {
+       rc = ioctl(fd, CHIOGPARAMS, &changer_info);
+       changer_info_init++;
+    }
+    return (rc);
+}
+
+/* Get the number of the first free slot
+ * return > 0 number of empty slot
+ * return = 0 no slot free
+ * return < 0 error
+ */
+int GetCurrentSlot(int fd, int drive)
+{
+    struct changer_element_status  ces;
+    int slot;
+    int i, rc;
+
+    get_changer_info(fd);
+
+    ces.ces_type = CHET_ST;
+    ces.ces_data = malloc(changer_info.cp_nslots);
+
+    rc = ioctl(fd, CHIOGSTATUS, &ces);
+    if (rc) {
+       dbprintf(("%s: changer status query failed: 0x%x %s\n",
+                       get_pname(), rc,strerror(errno)));
+       return -1;
+    }
+    for (slot = 0; slot < changer_info.cp_nslots; slot++)
+    {
+       i = ces.ces_data[slot] & CESTATUS_FULL;
+       dbprintf(("\tGetCurrentSlot slot %d = %d\n", slot, i));
+       if (!i)
+            return(slot);
+    }
+
+
+}
+
+int get_clean_state(int changerfd, char *changerdev, char *dev)
+{
+    return 0;
+
+}
+void eject_tape(char *tape)
+/* This function ejects the tape from the drive */
+{
+int mtfd;
+struct mtop mt_com;
+
+    if ((mtfd = open(tape, O_RDWR)) < 0) {
+        dbprintf(("eject_tape : failed\n"));
+        perror(tape);
+        exit(2);
+    }
+    mt_com.mt_op = MTOFFL;
+    mt_com.mt_count = 1;
+    if (ioctl(mtfd, MTIOCTOP, (char *)&mt_com) < 0) {
+/*
+    If the drive already ejected the tape due an error, or because it
+    was a cleaning tape, threre can be an error, which we should ignore 
+
+       perror(tape);
+       exit(2);
+*/
+    }
+    close(mtfd);
+}
+
+
+/* 
+ * this routine checks a specified slot to see if it is empty 
+ */
+int isempty(int fd, int slot)
+{
+struct changer_element_status  ces;
+int                            i,rc;
+int type=CHET_ST;
+
+    get_changer_info(fd);
+
+    ces.ces_type = type;
+    ces.ces_data = malloc(changer_info.cp_nslots);
+
+    rc = ioctl(fd, CHIOGSTATUS, &ces);
+    if (rc) {
+       dbprintf(("%s: changer status query failed: 0x%x %s\n",
+                       get_pname(), rc,strerror(errno)));
+       return -1;
+    }
+
+    i = ces.ces_data[slot] & CESTATUS_FULL;
+
+    free(ces.ces_data);
+    return !i;
+}
+
+/*
+ * find the first empty slot 
+ */
+int find_empty(int fd, int start, int count)
+{
+struct changer_element_status  ces;
+int                            i,rc;
+int type=CHET_ST;
+
+    get_changer_info(fd);
+
+    ces.ces_type = type;
+    ces.ces_data = malloc(changer_info.cp_nslots);
+
+    rc = ioctl(fd,CHIOGSTATUS,&ces);
+    if (rc) {
+       dbprintf(("%s: changer status query failed: 0x%x %s\n",
+                       get_pname(), rc, strerror(errno)));
+       return -1;
+    }
+
+    i = 0; 
+    while ((i < changer_info.cp_nslots)&&(ces.ces_data[i] & CESTATUS_FULL))
+       i++;
+    free(ces.ces_data);
+    return i;
+}
+
+/*
+ * returns one if there is a tape loaded in the drive 
+ */
+int drive_loaded(int fd, int drivenum)
+{
+struct changer_element_status  ces;
+int                            i,rc;
+int type=CHET_DT;
+
+    get_changer_info(fd);
+
+    ces.ces_type = type;
+    ces.ces_data = malloc(changer_info.cp_ndrives);
+
+    rc = ioctl(fd, CHIOGSTATUS, &ces);
+    if (rc) {
+       dbprintf(("%s: drive status query failed: 0x%x %s\n",
+                       get_pname(), rc, strerror(errno)));
+       return -1;
+    }
+
+    i = (ces.ces_data[drivenum] & CESTATUS_FULL);
+
+    free(ces.ces_data);
+    return i;
+}
+
+
+/*
+ * unloads the drive, putting the tape in the specified slot 
+ */
+int unload(int fd, int drive, int slot)
+{
+struct changer_move  move;
+int rc;
+
+    dbprintf(("unload : fd = %d, drive = %d, slot =%d\n",fd, drive, slot));
+
+    move.cm_fromtype = CHET_DT;
+    move.cm_fromunit = drive;
+    move.cm_totype = CHET_ST;
+    move.cm_tounit = slot;
+    move.cm_flags = 0;
+
+    rc = ioctl(fd, CHIOMOVE, &move);
+    if (rc){
+       dbprintf(("%s: drive unload failed (MOVE): 0x%x %s\n",
+               get_pname(), rc, strerror(errno)));
+       return(-2);
+    }
+    return 0;
+}
+
+
+/*
+ * moves tape from the specified slot into the drive 
+ */
+int load(int fd, int drive, int slot)
+{
+struct changer_move  move;
+int rc;
+
+    dbprintf(("load : fd = %d, drive = %d, slot =%d\n",fd, drive, slot));
+
+    move.cm_fromtype = CHET_ST;
+    move.cm_fromunit = slot;
+    move.cm_totype = CHET_DT;
+    move.cm_tounit = drive;
+    move.cm_flags = 0;
+
+    rc = ioctl(fd,CHIOMOVE,&move);
+    if (rc){
+       dbprintf(("%s: drive load failed (MOVE): 0x%x %s\n",
+               get_pname(), rc, strerror(errno)));
+       return(-2);
+    }
+    return(0);
+}
+
+int get_slot_count(int fd)
+{ 
+int rc;
+
+    rc = get_changer_info(fd);
+    if (rc) {
+        dbprintf(("%s: slot count query failed: 0x%x %s\n", 
+                       get_pname(), rc, strerror(errno)));
+        return -1;
+    }
+
+    return changer_info.cp_nslots;
+}
+
+int get_drive_count(int fd)
+{ 
+int rc;
+
+    rc = get_changer_info(fd);
+    if (rc) {
+        dbprintf(("%s: drive count query failed: 0x%x %s\n",
+                       get_pname(), rc, strerror(errno)));
+        return -1;
+    }
+
+    return changer_info.cp_ndrives;
+}
+
+/* This function should ask the drive if it is ready */
+int Tape_Ready ( char *tapedev , int wait)
+{
+  FILE *out=NULL;
+  int cnt=0;
+  
+  while ((cnt < wait) && (NULL==(out=fopen(tapedev,"w+")))){
+    cnt++;
+    sleep(1);
+  }
+  if (out != NULL)
+    fclose(out);
+  return 0;
+}
+
+int OpenDevice (char *tapedev)
+{
+  int DeviceFD;
+
+  DeviceFD = open(tapedev, O_RDWR);
+  return(DeviceFD);
+}
+
+int CloseDevice (char *device, int DeviceFD)
+{
+   int ret;
+
+   ret = close(DeviceFD);
+
+   return ret;
+}
+
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-default-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-defs.h b/changer-src/scsi-defs.h
new file mode 100644 (file)
index 0000000..3b8a36c
--- /dev/null
@@ -0,0 +1,1185 @@
+
+/*
+ * Copyright (c) 1998 T.Hepper
+ */
+#ifndef WORDS_BIGENDIAN
+#define LITTLE_ENDIAN_BITFIELDS
+#endif
+
+typedef enum { Input, Output } Direction_T; 
+typedef unsigned char CDB_T[12];
+
+#ifdef _AIX
+typedef unsigned int PackedBit;
+#define AIX_USE_GSC 1
+#else
+typedef unsigned char PackedBit;
+#endif
+
+#define INDEX_CHANGER 0
+#define INDEX_TAPE 1
+#define INDEX_TAPECTL 2
+
+#define CHG_MAXDEV 32          /* Maximum number of devices handled by pDev */
+                               /* Must be large to hold the result of ScanBus */
+
+#define TAPETYPE 4
+#define IMPORT 3
+#define STORAGE 2
+#define CHANGER 1
+
+#define TAG_SIZE 36
+#define MAXTRIES 100  /* How many tries until SCSI_TestUnitReady should return an ok */
+/*
+ * Sense Key definitions
+*/
+#define SENSE_NULL 0
+#define SENSE_RECOVERED_ERROR 1
+#define NOT_READY 2
+#define SENSE_NOT_READY 2
+#define SENSE_MEDIUM_ERROR 3
+#define SENSE_HARDWARE_ERROR 4
+#define HARDWARE_ERROR 4
+#define ILLEGAL_REQUEST 5
+#define SENSE_ILLEGAL_REQUEST 5
+#define UNIT_ATTENTION 6
+#define SENSE_UNIT_ATTENTION 6
+#define SENSE_DATA_PROTECT 7
+#define SENSE_BLANK_CHECK 8
+#define SENSE_VENDOR_SPECIFIC 0x9
+#define SENSE_ABORTED_COMMAND 0xb
+#define SENSE_VOLUME_OVERFLOW 0xd
+#define SENSE_CHG_ELEMENT_STATUS 0xe
+
+#define MAX_RETRIES 100
+
+#define INQUIRY_SIZE sizeof(SCSIInquiry_T)
+
+/*
+ * Return values from the OS dependent part
+ * of the SCSI interface
+ *
+ * The underlaying functions must decide what to do
+ */
+#define SCSI_ERROR -1
+#define SCSI_OK 0
+#define SCSI_SENSE 1
+#define SCSI_BUSY 2
+#define SCSI_CHECK 3
+
+
+/*
+ *  SCSI Commands
+*/
+#define SC_COM_TEST_UNIT_READY 0
+#define SC_COM_REWIND 0x1
+#define SC_COM_REQUEST_SENSE 0x3
+#define SC_COM_IES 0x7
+#define SC_COM_INQUIRY 0x12
+#define SC_COM_MODE_SELECT 0x15
+#define SC_COM_ERASE 0x19
+#define SC_COM_MODE_SENSE 0x1A
+#define SC_COM_UNLOAD 0x1B
+#define SC_COM_LOCATE 0x2B
+#define SC_COM_LOG_SELECT 0x4C
+#define SC_COM_LOG_SENSE 0x4d
+#define SC_MOVE_MEDIUM 0xa5
+#define SC_COM_RES 0xb8
+/*
+ * Define for LookupDevice
+ */
+#define LOOKUP_NAME 1
+#define LOOKUP_FD 2
+#define LOOKUP_TYPE 3
+#define LOOKUP_CONFIG 4
+/* 
+ * Define for the return codes from SenseHandler
+ */
+#define SENSE_ABORT -1
+#define SENSE_IGNORE 0
+#define SENSE_RETRY 2
+#define SENSE_IES 3
+#define SENSE_TAPE_NOT_ONLINE 4
+#define SENSE_TAPE_NOT_LOADED 5
+#define SENSE_NO 6
+#define SENSE_TAPE_NOT_UNLOADED 7
+#define SENSE_CHM_FULL 8
+/*
+ * Defines for the type field in the inquiry command
+ */
+#define TYPE_DISK 0
+#define TYPE_TAPE 1
+#define TYPE_PRINTER 2
+#define TYPE_PROCESSOR 3
+#define TYPE_WORM 4
+#define TYPE_CDROM 5
+#define TYPE_SCANNER 6
+#define TYPE_OPTICAL 7
+#define TYPE_CHANGER 8
+#define TYPE_COMM 9
+
+/* Defines for Tape_Status */
+#define TAPE_ONLINE 1        /* Tape is loaded */
+#define TAPE_BOT 2           /* Tape is at begin of tape */
+#define TAPE_EOT 4           /* Tape is at end of tape */
+#define TAPE_WR_PROT 8       /* Tape is write protected */
+#define TAPE_NOT_LOADED 16   /* Tape is not loaded */
+
+/* Defines for the function Tape_Ioctl */
+#define IOCTL_EJECT 0
+
+/* Defines for exit status */
+#define WARNING 1
+#define FATAL  2
+
+/* macros for building scsi msb array parameter lists */
+#ifndef B
+#define B(s,i) ((unsigned char)((s) >> i))
+#endif
+#ifndef B1
+#define B1(s)                           ((unsigned char)(s))
+#endif
+#define B2(s)                       B((s),8),   B1(s)
+#define B3(s)            B((s),16), B((s),8),   B1(s)
+#define B4(s) B((s),24), B((s),16), B((s),8),   B1(s)
+
+/* macros for converting scsi msb array to binary */
+#define V1(s)           (s)[0]
+#define V2(s)         (((s)[0] << 8) | (s)[1])
+#define V3(s)       (((((s)[0] << 8) | (s)[1]) << 8) | (s)[2])
+#define V4(s)     (((((((s)[0] << 8) | (s)[1]) << 8) | (s)[2]) << 8) | (s)[3])
+#define V5(s)   (((((((((s)[0] << 8) | (s)[1]) << 8) | (s)[2]) << 8) | (s)[3]) << 8) | (s)[4])
+#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 LABEL_DB_VERSION 2
+
+#define DEBUG_INFO 9
+#define DEBUG_ERROR 1
+#define DEBUG_ALL 0
+
+#define SECTION_ALL 0
+#define SECTION_INFO 1
+#define SECTION_SCSI 2
+#define SECTION_MAP_BARCODE 3
+#define SECTION_ELEMENT 4
+#define SECTION_BARCODE 5
+#define SECTION_TAPE 6
+#define SECTION_MOVE 7
+/*----------------------------------------------------------------------------*/
+/* 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 */
+  char *changerident;/* Config to use foe changer control, ovverride result from inquiry */
+  char *tapeident;   /* Same as above for the tape device */
+}config_t; 
+
+typedef struct {
+  int number_of_configs; /* How many different configurations are used */
+  int eject;             /* Do the drives need an eject-command */
+  int autoinv;           /* Do automaticly an inventory if an tape is not in the db or not active in the db */
+  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 */
+  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 */
+  config_t *conf;
+}changer_t;
+
+typedef struct {
+  char voltag[128];
+  char barcode[TAG_SIZE];
+  unsigned char valid;
+} LabelV1_T;
+
+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
+                                */
+
+  unsigned int LoadCount;      /* How many times has the tape been loaded */
+  unsigned int RecovError;     /* How many recovered errors */
+  unsigned int UnrecovError;   /* How man unrecoverd errors */
+  unsigned char valid;         /* Is this tape in the current magazin */
+} LabelV2_T;
+
+typedef enum {BARCODE_PUT, BARCODE_VOL, BARCODE_BARCODE, BARCODE_DUMP, RESET_VALID, FIND_SLOT, UPDATE_SLOT } MBCAction_T;
+typedef struct {
+  LabelV2_T data;
+  MBCAction_T action;
+} MBC_T;
+
+
+/* ======================================================= */
+/* RequestSense_T */
+/* ======================================================= */
+typedef struct  
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS 
+    PackedBit     ErrorCode:7;                    /* Byte 0 Bits 0-6 */
+    PackedBit     Valid:1;                              /* Byte 0 Bit 7    */
+#else 
+    PackedBit     Valid:1;                              /* Byte 0 Bit 7    */
+    PackedBit     ErrorCode:7;                    /* Byte 0 Bits 0-6 */
+#endif
+    unsigned char SegmentNumber;                  /* Byte 1 */ 
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     SenseKey:4;                     /* Byte 2 Bits 0-3 */
+    PackedBit     :1;                             /* Byte 2 Bit 4    */
+    PackedBit     RILI:1;                                /* Byte 2 Bit 5    */
+    PackedBit     REOM:1;                                /* Byte 2 Bit 6    */
+    PackedBit     Filemark:1;                           /* Byte 2 Bit 7    */
+#else 
+    PackedBit     Filemark:1;                           /* Byte 2 Bit 7    */
+    PackedBit     REOM:1;                                /* Byte 2 Bit 6    */
+    PackedBit     RILI:1;                                /* Byte 2 Bit 5    */
+    PackedBit     :1;                             /* Byte 2 Bit 4    */ 
+    PackedBit     SenseKey:4;                     /* Byte 2 Bits 0-3 */
+#endif
+    unsigned char Information[4];                 /* Bytes 3-6       */ 
+    unsigned char AdditionalSenseLength;          /* Byte 7          */   
+    unsigned char CommandSpecificInformation[4];  /* Bytes 8-11      */ 
+    unsigned char AdditionalSenseCode;            /* Byte 12         */
+    unsigned char AdditionalSenseCodeQualifier;   /* Byte 13         */ 
+    unsigned char Byte14;                          /* Byte 14         */ 
+    unsigned char Byte15;                           /* Byte 15         */ 
+    
+} RequestSense_T;     
+
+/* ======================================================= */
+/* ExtendedRequestSense_T */
+/* ======================================================= */
+typedef struct  
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS 
+    PackedBit     ErrorCode:7;                    /* Byte 0 Bits 0-6 */
+    PackedBit     Valid:1;                        /* Byte 0 Bit 7    */
+#else 
+    PackedBit     Valid:1;                        /* Byte 0 Bit 7    */
+    PackedBit     ErrorCode:7;                    /* Byte 0 Bits 0-6 */
+#endif
+    unsigned char SegmentNumber;                  /* Byte 1 */ 
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     SenseKey:4;                     /* Byte 2 Bits 0-3 */
+    PackedBit     :1;                             /* Byte 2 Bit 4    */
+    PackedBit     RILI:1;                         /* Byte 2 Bit 5    */
+    PackedBit     REOM:1;                         /* Byte 2 Bit 6    */
+    PackedBit     Filemark:1;                     /* Byte 2 Bit 7    */
+#else 
+    PackedBit     Filemark:1;                     /* Byte 2 Bit 7    */
+    PackedBit     REOM:1;                         /* Byte 2 Bit 6    */
+    PackedBit     RILI:1;                         /* Byte 2 Bit 5    */
+    PackedBit     :1;                             /* Byte 2 Bit 4    */ 
+    PackedBit     SenseKey:4;                     /* Byte 2 Bits 0-3 */
+#endif
+    unsigned char Information[4];                 /* Bytes 3-6       */ 
+    unsigned char AdditionalSenseLength;          /* Byte 7          */   
+    unsigned char LogParameterPageCode;           /* Bytes 8         */ 
+    unsigned char LogParameterCode;               /* Bytes 9         */ 
+    unsigned char Byte10;                         /* Bytes 10        */ 
+    unsigned char UnderrunOverrunCounter;         /* Bytes 11        */ 
+    unsigned char AdditionalSenseCode;            /* Byte 12         */
+    unsigned char AdditionalSenseCodeQualifier;   /* Byte 13         */ 
+    unsigned char Byte14;                         /* Byte 14         */ 
+    unsigned char Byte15;                         /* Byte 15         */ 
+    unsigned char ReadWriteDataErrorCounter[3];   /* Byte 16-18      */ 
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     LBOT:1;                         /* Byte 19 Bits 0 */
+    PackedBit     TNP:1;                          /* Byte 19 Bits 1 */
+    PackedBit     TME:1;                          /* Byte 19 Bits 2 */
+    PackedBit     ECO:1;                          /* Byte 19 Bits 3 */
+    PackedBit     ME:1;                           /* Byte 19 Bits 4 */
+    PackedBit     FPE:1;                          /* Byte 19 Bits 5 */
+    PackedBit     BPE:1;                          /* Byte 19 Bits 6 */
+    PackedBit     PF:1;                           /* Byte 19 Bits 7 */
+#else 
+    PackedBit     PF:1;                           /* Byte 19 Bits 7 */
+    PackedBit     BPE:1;                          /* Byte 19 Bits 6 */
+    PackedBit     FPE:1;                          /* Byte 19 Bits 5 */
+    PackedBit     ME:1;                           /* Byte 19 Bits 4 */
+    PackedBit     ECO:1;                          /* Byte 19 Bits 3 */
+    PackedBit     TME:1;                          /* Byte 19 Bits 2 */
+    PackedBit     TNP:1;                          /* Byte 19 Bits 1 */
+    PackedBit     LBOT:1;                         /* Byte 19 Bits 0 */
+#endif
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     FE:1;                           /* Byte 20 Bits 0 */
+    PackedBit     SSE:1;                          /* Byte 20 Bits 1 */
+    PackedBit     WEI:1;                          /* Byte 20 Bits 2 */
+    PackedBit     URE:1;                          /* Byte 20 Bits 3 */
+    PackedBit     FMKE:1;                         /* Byte 20 Bits 4 */
+    PackedBit     WP:1;                           /* Byte 20 Bits 5 */
+    PackedBit     TMD:1;                          /* Byte 20 Bits 6 */
+    PackedBit     :1;                             /* Byte 20 Bits 7 */
+#else 
+    PackedBit     :1;                             /* Byte 20 Bits 7 */
+    PackedBit     TMD:1;                          /* Byte 20 Bits 6 */
+    PackedBit     WP:1;                           /* Byte 20 Bits 5 */
+    PackedBit     FMKE:1;                         /* Byte 20 Bits 4 */
+    PackedBit     URE:1;                          /* Byte 20 Bits 3 */
+    PackedBit     WEI:1;                          /* Byte 20 Bits 2 */
+    PackedBit     SSE:1;                          /* Byte 20 Bits 1 */
+    PackedBit     FE:1;                           /* Byte 20 Bits 0 */
+#endif
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     WSEO:1;                         /* Byte 21 Bits 0 */
+    PackedBit     WSEB:1;                         /* Byte 21 Bits 1 */
+    PackedBit     PEOT:1;                         /* Byte 21 Bits 2 */
+    PackedBit     CLN:1;                          /* Byte 21 Bits 3 */
+    PackedBit     CLND:1;                         /* Byte 21 Bits 4 */
+    PackedBit     RRR:1;                          /* Byte 21 Bits 5 */
+    PackedBit     UCLN:1;                         /* Byte 21 Bits 6 */
+    PackedBit     :1;                             /* Byte 21 Bits 7 */
+#else 
+    PackedBit     :1;                             /* Byte 21 Bits 7 */
+    PackedBit     UCLN:1;                         /* Byte 21 Bits 6 */
+    PackedBit     RRR:1;                          /* Byte 21 Bits 5 */
+    PackedBit     CLND:1;                         /* Byte 21 Bits 4 */
+    PackedBit     CLN:1;                          /* Byte 21 Bits 3 */
+    PackedBit     PEOT:1;                         /* Byte 21 Bits 2 */
+    PackedBit     WSEB:1;                         /* Byte 21 Bits 1 */
+    PackedBit     WSEO:1;                         /* Byte 21 Bits 0 */
+#endif
+    unsigned char Byte21;                          /* Byte 22         */ 
+    unsigned char RemainingTape[3];                /* Byte 23-25      */ 
+    unsigned char TrackingRetryCounter;            /* Byte 26         */ 
+    unsigned char ReadWriteRetryCounter;           /* Byte 27         */ 
+    unsigned char FaultSymptomCode;                /* Byte 28         */ 
+    
+} ExtendedRequestSense_T;     
+
+/* ======================================================= */
+/*  ReadElementStatus_T */
+/* ======================================================= */
+typedef struct 
+{
+    unsigned char cmd;                           /* Byte 1 */
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     type : 4;
+    PackedBit     voltag :1;
+    PackedBit     lun :3;
+#else
+    PackedBit     lun :3;
+    PackedBit     voltag :1;
+    PackedBit     type : 4;
+#endif
+    unsigned char start[2];                    /* Byte 3-4 */
+    unsigned char number[2];                   /* Byte 5-6 */
+    unsigned char byte4;                       /* Byte 7 */
+    unsigned char length[4];                   /* Byte 8-11 */
+    unsigned char byte78[2];                   /* Byte 12-13 */
+} ReadElementStatus_T;
+
+/* ======================================================= */
+/* ElementStatusPage_T */
+/* ======================================================= */
+typedef struct 
+{
+    unsigned char type;     /* Byte 1 = Element Type Code*/
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     bitres  : 6;
+    PackedBit     avoltag : 1;
+    PackedBit     pvoltag : 1;
+#else
+    PackedBit     pvoltag : 1;
+    PackedBit     avoltag : 1;
+    PackedBit     bitres  : 6;
+#endif
+    unsigned char length[2];    /* Byte 2-3  = Element Descriptor Length */
+    unsigned char byte4;        /* Byte 4 */
+    unsigned char count[3];     /* Byte 5-7 = Byte Count of Descriptor Available */
+} ElementStatusPage_T;
+
+
+/* ======================================================= */
+/* ElementStatusData_T */
+/* ======================================================= */
+typedef struct 
+{
+    unsigned char first[2];    /* Byte 1-2 = First Element Adress Reported */
+    unsigned char number[2];   /* Byte 3-4 = Number of Elements Available */
+    unsigned char byte5;      /* Reserved */
+    unsigned char count[3];     /* Byte 6-8 = Byte Count of Report Available */
+} ElementStatusData_T;
+
+/* ======================================================= */
+/* MediumTransportElementDescriptor_T */
+/* ======================================================= */
+typedef struct 
+{
+    unsigned char address[2];   /* Byte 1-2 = Element Address */
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     full   : 1;
+    PackedBit     rsvd   : 1;
+    PackedBit     except : 1;
+    PackedBit     res    : 5;
+#else
+    PackedBit     res    : 5;
+    PackedBit     except : 1;
+    PackedBit     rsvd   : 1;
+    PackedBit     full   : 1;
+#endif
+    unsigned char byte4;        /* Byte 4      */
+    unsigned char asc;          /* Byte 5 ASC  */
+    unsigned char ascq;         /* Byte 6 ASCQ */
+    unsigned char byte79[3];    /* Byte 7-9    */
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     byte10res : 6;
+    PackedBit     invert : 1;
+    PackedBit     svalid : 1;
+#else
+    PackedBit     svalid : 1;
+    PackedBit     invert : 1;
+    PackedBit     byte10res : 6;
+#endif
+    unsigned char source[2];
+  unsigned char pvoltag[36];
+  unsigned char res4[4];
+} MediumTransportElementDescriptor_T;
+
+/* ======================================================= */
+/* ImportExportElementDescriptor_T */
+/* ======================================================= */
+typedef struct 
+{
+  unsigned char address[2];   /* Byte 1 = Element Address */
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+  PackedBit     full   : 1;
+  PackedBit     impexp : 1;
+  PackedBit     except : 1;
+  PackedBit     access : 1;
+  PackedBit     exenab : 1;
+  PackedBit     inenab : 1;
+  PackedBit     res    : 2;
+#else
+  PackedBit     res    : 2;
+  PackedBit     inenab : 1;
+  PackedBit     exenab : 1;
+  PackedBit     access : 1;
+  PackedBit     except : 1;
+  PackedBit     rsvd   : 1;
+  PackedBit     full   : 1;
+#endif
+    unsigned char byte4;
+    unsigned char asc;
+    unsigned char ascq;
+    unsigned char byte79[3];
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     byte10res : 6;
+    PackedBit     invert : 1;
+    PackedBit     svalid : 1;
+#else
+    PackedBit     svalid : 1;
+    PackedBit     invert : 1;
+    PackedBit     byte10res : 6;
+#endif
+    unsigned char source[2];
+  unsigned char pvoltag[36];
+  unsigned char res4[4];
+  unsigned char mediadomain[1];
+  unsigned char mediatype[1];
+  unsigned char res5[2];
+} ImportExportElementDescriptor_T;
+
+/* ======================================================= */
+/* StorageElementDescriptor_T */
+/* ======================================================= */
+typedef struct 
+{
+    unsigned char address[2];
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     full   : 1;
+    PackedBit     rsvd   : 1;
+    PackedBit     except : 1;
+    PackedBit     access : 1;
+    PackedBit     res    : 4;
+#else
+    PackedBit     res    : 4;
+    PackedBit     access : 1;
+    PackedBit     except : 1;
+    PackedBit     rsvd   : 1;
+    PackedBit     full   : 1;
+#endif
+    unsigned char res1;
+    unsigned char asc;
+    unsigned char ascq;
+    unsigned char res2[3];
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     res3   : 6;
+    PackedBit     invert : 1;
+    PackedBit     svalid : 1;
+#else
+    PackedBit     svalid : 1;
+    PackedBit     invert : 1;
+    PackedBit     res3   : 6;
+#endif
+    unsigned char source[2];
+  unsigned char pvoltag[36];
+  unsigned char res4[4];
+  unsigned char mediadomain[1];
+  unsigned char mediatype[1];
+  unsigned char res5[2];
+} StorageElementDescriptor_T;
+
+/* ======================================================= */
+/* DataTransferElementDescriptor_T */
+/* ======================================================= */
+typedef struct 
+{
+    unsigned char address[2];
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     full    : 1;
+    PackedBit     rsvd    : 1;
+    PackedBit     except  : 1;
+    PackedBit     access  : 1;
+    PackedBit     res     : 4;
+#else
+    PackedBit     res     : 4;
+    PackedBit     access  : 1;
+    PackedBit     except  : 1;
+    PackedBit     rsvd    : 1;
+    PackedBit     full    : 1;
+#endif
+    unsigned char res1;
+    unsigned char asc;
+    unsigned char ascq;
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     lun     : 3;
+    PackedBit     rsvd1   : 1;
+    PackedBit     luvalid : 1;
+    PackedBit     idvalid : 1;
+    PackedBit     rsvd2   : 1;
+    PackedBit     notbus  : 1;
+#else
+    PackedBit     notbus  : 1;
+    PackedBit     rsvd2   : 1;
+    PackedBit     idvalid : 1;
+    PackedBit     luvalid : 1;
+    PackedBit     rsvd1   : 1;
+    PackedBit     lun     : 3;
+#endif
+    unsigned char scsi;
+    unsigned char res2;
+#ifdef LITTLE_ENDIAN_BITFIELDS        
+    PackedBit     res3    : 6;
+    PackedBit     invert  : 1;
+    PackedBit     svalid  : 1;
+#else
+    PackedBit     svalid  : 1;
+    PackedBit     invert  : 1;
+    PackedBit     res3    : 6;
+#endif
+    unsigned char source[2];
+  unsigned char pvoltag[36];
+    unsigned char res4[42];
+} DataTransferElementDescriptor_T;
+
+/* ======================================================= */
+/* SCSIInquiry_T */
+/* ======================================================= */
+typedef struct
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit     type : 5;
+    PackedBit     qualifier : 3;
+
+    PackedBit     type_modifier : 7;
+    PackedBit     removable : 1;
+
+    PackedBit     ansi_version : 3;
+    PackedBit     ecma_version : 3;
+    PackedBit     iso_version : 2;
+
+    PackedBit     data_format : 4;
+    PackedBit     res3_54 : 2;
+    PackedBit     termiop : 1;
+    PackedBit     aenc : 1;
+#else
+    PackedBit     qualifier : 3;
+    PackedBit     type : 5;
+  
+    PackedBit     removable : 1;
+    PackedBit     type_modifier : 7;
+  
+    PackedBit     iso_version : 2;
+    PackedBit     ecma_version : 3;
+    PackedBit     ansi_version : 3;
+  
+    PackedBit     aenc : 1;
+    PackedBit     termiop : 1;
+    PackedBit     res3_54 : 2;
+    PackedBit     data_format : 4;
+#endif
+  
+    unsigned char add_len;
+  
+    unsigned char  res2;
+    unsigned char res3;
+  
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit     softreset : 1;
+    PackedBit     cmdque : 1;
+    PackedBit     res7_2 : 1;
+    PackedBit     linked  : 1;
+    PackedBit     sync : 1;
+    PackedBit     wbus16 : 1;
+    PackedBit     wbus32 : 1;
+    PackedBit     reladr : 1;
+#else
+    PackedBit     reladr : 1;
+    PackedBit     wbus32 : 1;
+    PackedBit     wbus16 : 1;
+    PackedBit     sync : 1;
+    PackedBit     linked  : 1;
+    PackedBit     res7_2 : 1;
+    PackedBit     cmdque : 1;
+    PackedBit     softreset : 1;
+#endif
+    char vendor_info[8];
+    char prod_ident[16];
+    char prod_version[4];
+    char vendor_specific[20];
+} SCSIInquiry_T;
+
+/* ======================================================= */
+/* ModeSenseHeader_T */
+/* ======================================================= */
+typedef struct
+{
+    unsigned char DataLength;
+    unsigned char MediumType;
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit Speed:4;
+    PackedBit BufferedMode:3;
+    PackedBit WP:1;
+#else
+    PackedBit WP:1;
+    PackedBit BufferedMode:3;
+    PackedBit Speed:4;
+#endif
+    unsigned char BlockDescLength;
+} ModeSenseHeader_T;
+/* ======================================================= */
+/* ModeBlockDescriptor_T */
+/* ======================================================= */
+typedef struct 
+{
+    unsigned char DensityCode;
+    unsigned char NumberOfBlocks[3];
+    unsigned char Reserved;
+    unsigned char BlockLength[3];
+} ModeBlockDescriptor_T;
+/* ======================================================= */
+/* LogSenseHeader_T */
+/* ======================================================= */
+typedef struct 
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode:6;
+    PackedBit Reserved:2;
+#else
+    PackedBit Reserved:2;
+    PackedBit PageCode:6;
+#endif
+    unsigned char Reserved1;
+    unsigned char PageLength[2];
+} LogSenseHeader_T ;
+/* ======================================================= */
+/* LogParameters_T */
+/* ======================================================= */
+typedef struct
+{
+    unsigned char ParameterCode[2];
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit LP:1;
+    PackedBit RSCD:1;
+    PackedBit TMC:1;
+    PackedBit ETC:1;
+    PackedBit TSD:1;
+    PackedBit DS:1;
+    PackedBit DU:1;
+#else
+    PackedBit DU:1;
+    PackedBit DS:1;
+    PackedBit TSD:1;
+    PackedBit ETC:1;
+    PackedBit TMC:1;
+    PackedBit RSCD:1;
+    PackedBit LP:1;
+#endif
+    char ParameterLength;
+} LogParameter_T;
+/*
+ * Pages returned by the MODE_SENSE command
+ */
+typedef struct {
+    unsigned char SenseDataLength;
+    char res[3];
+} ParameterListHeader_T;
+/* ======================================================= */
+/* ReadWriteErrorRecoveryPage_T */
+/* ======================================================= */
+typedef struct 
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode : 6;
+    PackedBit res      : 1;
+    PackedBit PS       : 1;
+#else
+    PackedBit PS       : 1;
+    PackedBit res      : 1;
+    PackedBit PageCode : 6;
+#endif
+    unsigned char ParameterListLength;
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit dcr  :1;  /* Disable ECC Correction */
+    PackedBit dte  :1;  /* Disable Transfer on Error */
+    PackedBit per  :1;  /* Enable Post  Error reporting */
+    PackedBit eer  :1;  /* Enable early recovery */
+    PackedBit res1 :1;
+    PackedBit tb   :1;  /* Transfer block (when not fully recovered) */
+    PackedBit res2 :1;
+    PackedBit res3 :1;
+#else
+    PackedBit res3 :1;
+    PackedBit res2 :1;
+    PackedBit tb   :1;
+    PackedBit res1 :1;
+    PackedBit eer  :1;
+    PackedBit per  :1;
+    PackedBit dte  :1;
+    PackedBit dcr  :1;
+#endif
+    unsigned char ReadRetryCount;
+    unsigned char res4[4];
+    unsigned char WriteRetryCount;
+    unsigned char res5[3];
+} ReadWriteErrorRecoveryPage_T; 
+/* ======================================================= */
+/* EDisconnectReconnectPage_T */
+/* ======================================================= */
+typedef struct 
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode : 6;
+    PackedBit RSVD     : 1;
+    PackedBit PS       : 1;
+#else
+    PackedBit PS       : 1;
+    PackedBit RSVD     : 1;
+    PackedBit PageCode : 6;
+#endif
+
+    unsigned char BufferFullRatio;
+    unsigned char BufferEmptyRatio;
+    unsigned char BusInactivityLimit[2];
+    unsigned char DisconnectTimeLimit[2];
+    unsigned char ConnectTimeLimit[2];
+    unsigned char MaximumBurstSize[2];
+
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit DTDC :2;
+    PackedBit res  :6;
+#else
+    PackedBit res  :6;
+    PackedBit DTDC :2;
+#endif
+    unsigned char res1[3];
+} DisconnectReconnectPage_T;
+
+/* ======================================================= */
+/* EAAPage_T */
+/* ======================================================= */
+typedef struct 
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode : 6;
+    PackedBit RSVD     : 1;
+    PackedBit PS       : 1;
+#else
+    PackedBit PS       : 1;
+    PackedBit RSVD     : 1;
+    PackedBit PageCode : 6;
+#endif
+    unsigned char ParameterListLength;
+    unsigned char MediumTransportElementAddress[2];
+    unsigned char NoMediumTransportElements[2];
+    unsigned char FirstStorageElementAddress[2];
+    unsigned char NoStorageElements[2];
+    unsigned char FirstImportExportElementAddress[2];
+    unsigned char NoImportExportElements[2];
+    unsigned char FirstDataTransferElementAddress[2];
+    unsigned char NoDataTransferElements[2];
+    unsigned char res[2];
+} EAAPage_T;    
+/* ======================================================= */
+/* TransPortGeometryDescriptorPage_T */
+/* ======================================================= */
+typedef struct {
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode : 6;
+    PackedBit RSVD     : 1;
+    PackedBit PS       : 1;
+#else
+    PackedBit PS       : 1;
+    PackedBit RSVD     : 1;
+    PackedBit PageCode : 6;
+#endif
+    unsigned char ParameterListLength;
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit Rotate    : 1;
+    PackedBit res       : 7;
+#else
+    PackedBit res       : 7;
+    PackedBit Rotate    : 1;
+#endif
+    unsigned char MemberNumber;
+} TransportGeometryDescriptorPage_T;  
+/* ======================================================= */
+/* DeviceCapabilitiesPage_T */
+/* ======================================================= */
+typedef struct
+{
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode : 6;
+    PackedBit RSVD     : 1;
+    PackedBit PS       : 1;
+#else
+    PackedBit PS       : 1;
+    PackedBit RSVD     : 1;
+    PackedBit PageCode : 6;
+#endif
+    unsigned char ParameterLength;
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit MT        : 1;
+    PackedBit ST        : 1;
+    PackedBit IE        : 1;
+    PackedBit DT        : 1;
+    PackedBit res1      : 4;
+#else
+    PackedBit res1      : 4;
+    PackedBit DT        : 1;
+    PackedBit IE        : 1;
+    PackedBit ST        : 1;
+    PackedBit MT        : 1;
+#endif
+    unsigned char res;
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit MT2MT     : 1;
+    PackedBit MT2ST     : 1;
+    PackedBit MT2IE     : 1;
+    PackedBit MT2DT     : 1;
+    PackedBit res2      : 4;
+#else
+    PackedBit res2      : 4;
+    PackedBit MT2DT     : 1;
+    PackedBit MT2IE     : 1;
+    PackedBit MT2ST     : 1;
+    PackedBit MT2MT     : 1;
+#endif
+
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit ST2MT     : 1;
+    PackedBit ST2ST     : 1;
+    PackedBit ST2IE     : 1;
+    PackedBit ST2DT     : 1;
+    PackedBit res3      : 4;
+#else
+    PackedBit res3      : 4;
+    PackedBit ST2DT     : 1;
+    PackedBit ST2IE     : 1;
+    PackedBit ST2ST     : 1;
+    PackedBit ST2MT     : 1;
+#endif
+
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit IE2MT     : 1;
+    PackedBit IE2ST     : 1;
+    PackedBit IE2IE     : 1;
+    PackedBit IE2DT     : 1;
+    PackedBit res4      : 4;
+#else
+    PackedBit res4      : 4;
+    PackedBit IE2DT     : 1;
+    PackedBit IE2IE     : 1;
+    PackedBit IE2ST     : 1;
+    PackedBit IE2MT     : 1;
+#endif
+
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit DT2MT     : 1;
+    PackedBit DT2ST     : 1;
+    PackedBit DT2IE     : 1;
+    PackedBit DT2DT     : 1;
+    PackedBit res5      : 4;
+#else
+    PackedBit res5      : 4;
+    PackedBit DT2DT     : 1;
+    PackedBit DT2IE     : 1;
+    PackedBit DT2ST     : 1;
+    PackedBit DT2MT     : 1;
+#endif
+    unsigned char res0819[12];
+} DeviceCapabilitiesPage_T;  
+/* ======================================================= */
+/* ModePageEXB10hLCD_T */
+/* ======================================================= */
+typedef struct ModePageEXB10hLCD
+{
+  unsigned char PageCode;
+  unsigned char ParameterListLength;
+
+#ifdef LITTLE_ENDIAN_BITFIELDS
+  PackedBit WriteLine4 : 1;
+  PackedBit WriteLine3 : 1;
+  PackedBit WriteLine2 : 1;
+  PackedBit WriteLine1 : 1;
+  PackedBit res        : 4;
+#else
+  PackedBit res        : 4;
+  PackedBit WriteLine1 : 1;
+  PackedBit WriteLine2 : 1;
+  PackedBit WriteLine3 : 1;
+  PackedBit WriteLine4 : 1;
+#endif
+  unsigned char reserved;
+  unsigned char line1[20];
+  unsigned char line2[20];
+  unsigned char line3[20];
+  unsigned char line4[20];
+} ModePageEXB10hLCD_T;
+/* ======================================================= */
+/* ModePageEXBBaudRatePage_T */
+/* ======================================================= */
+typedef struct ModePageEXBBaudRatePage
+{
+  unsigned char PageCode;
+  unsigned char ParameterListLength;
+  unsigned char BaudRate[2];
+} ModePageEXBBaudRatePage_T;
+/* ======================================================= */
+/* ModePageEXB120VendorUnique_T */
+/* ======================================================= */
+typedef struct ModePageEXB120VendorUnique
+{
+#ifdef  LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode : 6;
+    PackedBit RSVD0    : 1;
+    PackedBit PS       : 1;
+#else
+    PackedBit PS       : 1;
+    PackedBit RSVD0    : 1;
+    PackedBit PageCode : 6;
+#endif
+    unsigned char ParameterListLength;
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit MDC  : 2;
+    PackedBit NRDC : 1;
+    PackedBit RSVD : 1;
+    PackedBit NBL  : 1;
+    PackedBit PRTY : 1;
+    PackedBit UINT : 1;
+    PackedBit AINT : 1;
+#else
+    PackedBit AINT : 1;
+    PackedBit UINT : 1;
+    PackedBit PRTY : 1;
+    PackedBit NBL  : 1;
+    PackedBit RSVD : 1;
+    PackedBit NRDC : 1;
+    PackedBit MDC  : 2;
+#endif
+    unsigned char MaxParityRetries;
+    unsigned char DisplayMessage[60];
+} ModePageEXB120VendorUnique_T;
+/* ======================================================= */
+/* ModePageTreeFrogVendorUnique_T */
+/* ======================================================= */
+typedef struct ModePageTreeFrogVendorUnique
+{
+#ifdef  LITTLE_ENDIAN_BITFIELDS
+    PackedBit PageCode : 6;
+    PackedBit res0     : 1;
+    PackedBit PS       : 1;
+#else
+    PackedBit PS       : 1;
+    PackedBit res0     : 1;
+    PackedBit PageCode : 6;
+#endif
+    unsigned char ParameterListLength;
+#ifdef LITTLE_ENDIAN_BITFIELDS
+    PackedBit EBARCO  : 1;
+    PackedBit CHKSUM  : 1;
+    PackedBit res2    : 6;
+#else
+    PackedBit res2    : 6;
+    PackedBit CHKSUM  : 1;
+    PackedBit EBARCO  : 1;
+#endif
+    unsigned char res3;
+    unsigned char res4;
+    unsigned char res5;
+    unsigned char res6;
+    unsigned char res7;
+    unsigned char res8;
+    unsigned char res9;
+} ModePageTreeFrogVendorUnique_T;
+/* ======================================================= */
+/* ElementInfo_T */
+/* ======================================================= */
+typedef struct ElementInfo
+{
+    int type;       /* CHANGER - 1, STORAGE - 2, TAPE - 4 */
+    int address;    /* Adress of this Element */
+    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 scsi; /* if DTE, which scsi address */
+
+  PackedBit svalid : 1;
+  PackedBit invert : 1;
+  PackedBit full   : 1;
+  PackedBit impexp : 1;
+  PackedBit except : 1;
+  PackedBit access : 1;
+  PackedBit inenab : 1;
+  PackedBit exenab : 1;
+
+} ElementInfo_T;
+
+
+
+typedef struct {
+    char *ident;                  /* Name of the device from inquiry */
+    char *type;                   /* Device Type, tape|robot */
+    int (*function_move)(int, int, int);
+    int (*function_status)(int, int);
+    int (*function_reset_status)(int);
+    int (*function_free)();
+    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 *);
+} ChangerCMD_T ;
+
+typedef struct {
+    unsigned char command;        /* The SCSI command byte */
+    int length;                   /* How long */
+    char *name;                   /* Name of the command */
+} SC_COM_T;
+
+typedef struct OpenFiles {
+    int fd;                       /* The filedescriptor */
+#ifdef HAVE_CAM_LIKE_SCSI
+    struct cam_device *curdev;
+#endif
+  unsigned char avail;          /* Is this device available */
+  unsigned char devopen;        /* Is the device open */
+  unsigned char inqdone;        /* Did we try to get device infos, was an open sucessfull */
+  unsigned char SCSI;           /* Can we send SCSI commands */
+  int flags;                    /* Can be used for some flags ... */
+  char *dev;                    /* The device which is used */
+  char *type;                  /* Type of device, tape/changer */
+  char *ConfigName;             /* The name in the config */
+  char ident[17];               /* The identifier from the inquiry command */
+  ChangerCMD_T *functions;      /* Pointer to the function array for this device */
+  SCSIInquiry_T *inquiry;       /* The result from the Inquiry */
+} OpenFiles_T;
+
+typedef struct LogPageDecode {
+    int LogPage;
+    char *ident;
+    void (*decode)(LogParameter_T *, int);
+} 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 */
+} SenseType_T;                                                                                    
+
+/* ======================================================= */
+/* Funktion-Declaration */
+/* ======================================================= */
+int SCSI_OpenDevice(int );
+int OpenDevice(int ,char *DeviceName, char *ConfigName, char *ident);
+
+int SCSI_CloseDevice(int DeviceFD); 
+int CloseDevice(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) ;
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int 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);
+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));
+
+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);
+int BarCode(int fd);
+int MapBarCode(char *labelfile, MBC_T *);
+
+int Tape_Ready(int fd, int wait_time);
+
+void Inventory(char *labelfile, int drive, int eject, int start, int stop, int clean);
+void ChangerDriverVersion();
+void PrintConf();
+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();
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-hpux.c b/changer-src/scsi-hpux.c
new file mode 100644 (file)
index 0000000..d0f50f7
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * 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: scsi-hpux.c,v 1.4.4.9.6.1 2002/08/22 17:41:10 martinea Exp $
+ *
+ *     scsi-chio.c -- library routines to handle the changer
+ *                     support for chio based systems
+ *
+ *     Author: Eric Schnoebelen, eric@cirr.com
+ *     interface based on work by: Larry Pyeatt, pyeatt@cs.colostate.edu 
+ *     Copyright: 1997, 1998 Eric Schnoebelen
+ *             
+ *      Michael C. Povel 03.06.98 added dummy for eject_tape
+ */
+
+#include "amanda.h"
+
+#if defined(HAVE_HPUX_SCSI_CHIO)
+# include <sys/scsi.h>
+# include <sys/mtio.h>  /* for eject_tape ioctls */
+
+char *moddesc = "@(#)" __FILE__
+               ": HP/UX SCSI changer support routines @(#)";
+
+/* 
+ * a cache of the robotics information, for use elsewhere
+ */
+static struct element_addresses changer_info;
+static int changer_info_init = 0;
+
+
+/* Get the number of the first free slot
+ * return > 0 number of empty slot
+ * return = 0 no slot free
+ * return < 0 error
+ */
+int GetCurrentSlot(int fd)
+{
+
+}
+
+static int get_changer_info(fd)
+{
+int rc = 0;
+
+    if (!changer_info_init) {
+       rc = ioctl(fd, SIOC_ELEMENT_ADDRESSES, &changer_info);
+       changer_info_init++;
+    }
+    return (rc);
+}
+
+int get_clean_state(char *dev)
+{
+#if 0
+/*
+  This code works for Linux .... 
+  maybe someone can do something like this under HPUX
+*/
+    int status;
+    unsigned char *cmd;
+    unsigned char buffer[255];
+    int filenr;
+
+    if ((filenr = open(dev, O_RDWR)) < 0) {
+        perror(dev);
+        return 0;
+    }
+    memset(buffer, 0, sizeof(buffer));
+
+    *((int *) buffer) = 0;      /* length of input data */
+    *(((int *) buffer) + 1) = 100;     /* length of output buffer */
+
+    cmd = (char *) (((int *) buffer) + 2);
+
+    cmd[0] = 0x4d;         /* LOG SENSE  */
+    cmd[2] = (1 << 6)|0x33;     /* PageControl, PageCode */
+    cmd[7] = 00;                 /* allocation length hi */
+    cmd[8] = 100;                 /* allocation length lo */
+
+    status = ioctl(filenr, 1 /* SCSI_IOCTL_SEND_COMMAND */ , buffer);
+
+    if (status)
+        return 0;
+
+    if ((buffer[16] & 0x1) == 1)
+          return 1;
+
+#endif
+    return 0;
+
+}
+
+
+void eject_tape(char *tape)
+     /* This function ejects the tape from the drive */
+{
+/*
+  This code works for Linux .... 
+  This code works for HPUX too, see 'man 7 mt'
+*/
+    int mtfd;
+    struct mtop mt_com;
+
+    if ((mtfd = open(tape, O_RDWR)) < 0) {
+        perror(tape);
+        exit(2);
+    }
+    mt_com.mt_op = MTOFFL;
+    mt_com.mt_count = 1;
+    if (ioctl(mtfd, MTIOCTOP, (char *)&mt_com) < 0) {
+/* Ignore the error
+       perror(tape);
+       exit(2);
+*/
+    }
+    close(mtfd);
+}
+
+/* 
+ * this routine checks a specified slot to see if it is empty 
+ */
+int isempty(int fd, int slot)
+{
+struct element_status es;
+int rc;
+
+    /*
+     * fill the cache as required
+     */
+    get_changer_info(fd);
+
+    es.element = changer_info.first_storage + slot;
+
+    rc = ioctl(fd, SIOC_ELEMENT_STATUS, &es);
+    if (rc) {
+       fprintf(stderr, "%s: element status query failed: 0x%x %s\n",
+                               get_pname(), rc, strerror(errno));
+       return(-1);
+    }
+
+    return !es.full;
+}
+
+/*
+ * find the first empty slot 
+ */
+int find_empty(int fd)
+{
+struct element_status  es;
+int i, rc;
+
+    get_changer_info(fd);
+
+    i = changer_info.first_storage;
+    do {
+       es.element = i++;
+       rc = ioctl(fd, SIOC_ELEMENT_STATUS, &es);
+    } while ( (i <= (changer_info.first_storage + changer_info.num_storages))
+               && !rc && es.full);
+
+    if (rc) {
+       fprintf(stderr,"%s: element status query failed: 0x%x %s\n",
+                               get_pname(), rc, strerror(errno));
+       return -1;
+    }
+    return (i - changer_info.first_storage - 1);
+}
+
+/*
+ * returns one if there is a tape loaded in the drive 
+ */
+int drive_loaded(int fd, int drivenum)
+{
+struct element_status  es;
+int                            i,rc;
+
+    get_changer_info(fd);
+
+    es.element = changer_info.first_data_transfer + drivenum;
+
+    rc = ioctl(fd, SIOC_ELEMENT_STATUS, &es);
+    if (rc) {
+       fprintf(stderr,"%s: drive status quer failed: 0x%x %s\n",
+                               get_pname(), rc, strerror(errno));
+       return(-1);
+    }
+
+    return es.full;
+}
+
+
+/*
+ * unloads the drive, putting the tape in the specified slot 
+ */
+int unload(int fd, int drive, int slot)
+{
+struct move_medium_parms  move;
+int rc;
+
+    get_changer_info(fd);
+
+    /*
+     * pick the first transport, just for simplicity
+     */
+    move.transport = changer_info.first_transport;
+
+    move.source = changer_info.first_data_transfer + drive;
+    move.destination = changer_info.first_storage + slot;
+    move.invert = 0;
+
+    rc = ioctl(fd, SIOC_MOVE_MEDIUM, &move);
+    if (rc){
+       fprintf(stderr,"%s: move medium command failed: 0x%x %s\n",
+               get_pname(), rc, strerror(errno));
+       return(-2);
+    }
+    return 0;
+}
+
+
+/*
+ * moves tape from the specified slot into the drive 
+ */
+int load(int fd, int drive, int slot)
+{
+struct move_medium_parms  move;
+int rc;
+
+    get_changer_info(fd);
+
+    /*
+     * use the first transport defined in the changer, for lack of a
+     * better choice..
+     */
+    move.transport = changer_info.first_transport;
+
+    move.source = changer_info.first_storage + slot;
+    move.destination = changer_info.first_data_transfer + drive;
+    move.invert = 0;
+
+    rc = ioctl(fd, SIOC_MOVE_MEDIUM,&move);
+    if (rc){
+       fprintf(stderr,"%s: drive load failed (MOVE): 0x%x %s\n",
+               get_pname(), rc, strerror(errno));
+       return(-2);
+    }
+    return (rc);
+}
+
+int get_slot_count(int fd)
+{ 
+int rc;
+
+    rc = get_changer_info(fd);
+    if (rc) {
+        fprintf(stderr, "%s: storage size query failed: 0x%x %s\n", get_pname(),
+                                               rc, strerror(errno));
+        return -1;
+    }
+
+    return(changer_info.num_storages);
+
+}
+
+int get_drive_count(int fd)
+{ 
+    int rc;
+
+    rc = get_changer_info(fd);
+    if (rc) {
+        fprintf(stderr, "%s: drive count query failed: 0x%x %s\n", get_pname(),
+                                               rc, strerror(errno));
+        return -1;
+    }
+
+    return changer_info.num_data_transfers;
+}
+
+/* This function should ask the drive if it is ready */
+int Tape_Ready(char *tapedev, char *changerdev, int changerfd, int wait)
+{
+  FILE *out=NULL;
+  int cnt=0;
+
+  if (strcmp(tapedev, changerdev) == 0)
+    {
+      sleep(wait);
+      return(0);
+    }
+
+  while ((cnt<wait) && (NULL==(out=fopen(tapedev,"w+")))){
+    cnt++;
+    sleep(1);
+  }
+  if (out != NULL)
+    fclose(out);
+  return 0;
+}
+
+int OpenDevice(char * tapedev)
+{
+  int DeviceFD;
+
+  DeviceFD = open(tapedev, O_RDWR);
+  return(DeviceFD);
+}
+
+int CloseDevice(int DeviceFD)
+{
+  int ret;
+
+  ret = close(DeviceFD);
+  return(ret);
+}
+
+#endif
diff --git a/changer-src/scsi-hpux_new.c b/changer-src/scsi-hpux_new.c
new file mode 100644 (file)
index 0000000..56d2976
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * 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: scsi-hpux_new.c,v 1.1.2.12.4.1.2.4 2003/06/05 20:44:23 martinea Exp $
+ *
+ * Interface to execute SCSI commands on an HP-UX Workstation
+ *
+ * Copyright (c) Thomas Hepper th@ant.han.de
+ */
+
+
+#include <amanda.h>
+
+#ifdef HAVE_HPUX_LIKE_SCSI
+
+# ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+/*
+#ifdef HAVE_STDIO_H
+*/
+#include <stdio.h>
+/*
+#endif
+*/
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_SCSI_H
+#include <sys/scsi.h>
+#endif
+
+#include <sys/mtio.h>
+
+#include <scsi-defs.h>
+
+void SCSI_OS_Version()
+{
+#ifndef lint
+    static char rcsid[] = "$Id: scsi-hpux_new.c,v 1.1.2.12.4.1.2.4 2003/06/05 20:44:23 martinea Exp $";
+   DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
+#endif
+}
+
+int SCSI_OpenDevice(int ip)
+{
+  extern OpenFiles_T *pDev;
+  int DeviceFD;
+  int i;
+
+  if (pDev[ip].inqdone == 0)
+    {
+      pDev[ip].inqdone = 1;
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) > 0)
+        {
+          pDev[ip].avail = 1;
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].devopen = 1;
+          pDev[ip].SCSI = 0;
+          pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
+          
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+            {
+              if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
+                {
+                  for (i=0;i < 16;i++)
+                    pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+                  for (i=15; i >= 0 && !isalnum(pDev[ip].inquiry->prod_ident[i]) ; i--)
+                    {
+                      pDev[ip].inquiry->prod_ident[i] = '\0';
+                    }
+                  pDev[ip].SCSI = 1;
+
+                 if (pDev[ip].inquiry->type == TYPE_TAPE)
+                 {
+                         pDev[ip].type = stralloc("tape");
+                 }
+
+                 if (pDev[ip].inquiry->type == TYPE_CHANGER)
+                 {
+                         pDev[ip].type = stralloc("changer");
+                 }
+
+                  PrintInquiry(pDev[ip].inquiry);
+                  return(1);    
+                } else {
+                  close(DeviceFD);
+                  free(pDev[ip].inquiry);
+                  return(0);
+              }
+            } else {
+              close(DeviceFD);
+              free(pDev[ip].inquiry);
+              pDev[ip].inquiry = NULL;
+              return(1);
+            }
+          return(1);
+        }
+    } else {
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) > 0)
+        {
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].devopen = 1;
+          return(1);
+        }
+    }
+
+  return(0); 
+}
+
+int SCSI_CloseDevice(int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  int ret;
+
+  ret = close(pDev[DeviceFD].fd);
+  pDev[DeviceFD].devopen = 0;
+  return(ret);
+}
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *RequestSense,
+                        int RequestSenseLength)
+{
+  extern OpenFiles_T *pDev;
+  struct sctl_io sctl_io;
+  extern int errno;
+  int Retries = 3;
+  int Zero = 0, Result;
+  
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(SCSI_ERROR);
+    }
+
+
+  memset(&sctl_io, '\0', sizeof(struct sctl_io));
+
+  sctl_io.flags = 0;  
+  sctl_io.max_msecs = 240000;
+  /* Set the cmd */
+  memcpy(sctl_io.cdb, CDB, CDB_Length);
+  sctl_io.cdb_length = CDB_Length;
+  /* Data buffer for results */
+  sctl_io.data = DataBuffer;
+  sctl_io.data_length = (unsigned)DataBufferLength;
+
+  switch (Direction) 
+    {
+    case Input:
+      sctl_io.flags = sctl_io.flags | SCTL_READ;
+      break;
+    case Output:
+      break;
+    }
+
+  while (--Retries > 0) {
+
+    if (pDev[DeviceFD].devopen == 0)
+      SCSI_OpenDevice(DeviceFD);
+
+    DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
+    Result = ioctl(pDev[DeviceFD].fd, SIOC_IO, &sctl_io);
+    SCSI_CloseDevice(DeviceFD);
+    if (Result < 0)
+      {
+        return(SCSI_ERROR);
+      }
+    
+    SCSI_CloseDevice(DeviceFD);
+
+    memcpy(RequestSense, 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);
+}
+/*
+ * Send the command to the device with the
+ * ioctl interface
+ */
+int Tape_Ioctl( int DeviceFD, int command)
+{
+  extern OpenFiles_T *pDev;
+  struct mtop mtop;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  switch (command)
+    {
+    case IOCTL_EJECT:
+      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));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
+
+  SCSI_CloseDevice(DeviceFD);
+  return(ret);  
+}
+
+
+
+int Tape_Status( int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  struct mtget mtget;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    SCSI_OpenDevice(DeviceFD);
+
+  if (ioctl(pDev[DeviceFD].fd, MTIOCGET, &mtget) != 0)
+  {
+     dbprintf(("Tape_Status error ioctl %d\n",errno));
+     SCSI_CloseDevice(DeviceFD);
+     return(-1);
+  }
+
+  dbprintf(("ioctl -> mtget.mt_gstat %X\n",mtget.mt_gstat));
+  if (GMT_ONLINE(mtget.mt_gstat))
+  {
+    ret = TAPE_ONLINE;
+  }
+
+  if (GMT_BOT(mtget.mt_gstat))
+  {
+    ret = ret | TAPE_BOT;
+  }
+
+  if (GMT_EOT(mtget.mt_gstat))
+  {
+    ret = ret | TAPE_EOT;
+  }
+
+  if (GMT_WR_PROT(mtget.mt_gstat))
+  {
+    ret = ret | TAPE_WR_PROT;
+  }
+
+  SCSI_CloseDevice(DeviceFD);
+  return(ret); 
+}
+
+int ScanBus(int print)
+{
+/*
+  Not yet
+*/
+  return(-1);
+}
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-irix.c b/changer-src/scsi-irix.c
new file mode 100644 (file)
index 0000000..1e635c9
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * 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: scsi-irix.c,v 1.1.2.13.4.1.2.5 2003/01/26 19:20:57 martinea Exp $
+ *
+ * Interface to execute SCSI commands on an SGI Workstation
+ *
+ * Copyright (c) Thomas Hepper th@ant.han.de
+ */
+
+
+#include <amanda.h>
+
+#ifdef HAVE_IRIX_LIKE_SCSI
+
+/*
+#ifdef HAVE_STDIO_H
+*/
+#include <stdio.h>
+/*
+#endif
+*/
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <sys/scsi.h>
+#include <sys/dsreq.h>
+#include <sys/mtio.h>
+
+#include <scsi-defs.h>
+
+void SCSI_OS_Version()
+{
+#ifndef lint
+   static char rcsid[] = "$Id: scsi-irix.c,v 1.1.2.13.4.1.2.5 2003/01/26 19:20:57 martinea Exp $";
+   DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
+#endif
+}
+
+
+/*
+ */
+int SCSI_OpenDevice(int ip)
+{
+  extern OpenFiles_T *pDev;
+  int DeviceFD;
+  int i;
+  
+  if (pDev[ip].inqdone == 0)
+    {
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR | O_EXCL)) > 0)
+        {
+          pDev[ip].inqdone = 1;          pDev[ip].SCSI = 0;
+          pDev[ip].avail = 1;
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+            {
+              if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
+                {
+                  for (i=0;i < 16 ;i++)
+                    pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+                  for (i=15; i >= 0 && !isalnum((int)pDev[ip].ident[i]) ; i--)
+                    {
+                      pDev[ip].ident[i] = '\0';
+                    }
+                  pDev[ip].SCSI = 1;
+                  close(DeviceFD);
+
+                 if (pDev[ip].inquiry->type == TYPE_TAPE)
+                 {
+                         pDev[ip].type = stralloc("tape");
+                 }
+
+                 if (pDev[ip].inquiry->type == TYPE_CHANGER)
+                 {
+                         pDev[ip].type = stralloc("changer");
+                 }
+
+                  PrintInquiry(pDev[ip].inquiry);
+                  return(1);
+                } else { /* ! TYPE_TAPE ! TYPE_CHANGER */
+                  close(DeviceFD);
+                  free(pDev[ip].inquiry);
+                  pDev[ip].inquiry = NULL;
+                  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);
+        }
+    } else {
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR | O_EXCL)) > 0)
+        {
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].devopen = 1;
+          return(1);
+        } else {
+          pDev[ip].devopen = 0;
+          return(0);
+        }
+    }
+  return(0); 
+}
+
+int SCSI_CloseDevice(int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  int ret = 0;
+  
+  if (pDev[DeviceFD].devopen == 1)
+    {
+      pDev[DeviceFD].devopen = 0;
+      ret = close(pDev[DeviceFD].fd);
+    }
+
+  return(ret);
+}
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *pRequestSense,
+                        int RequestSenseLength)
+{
+  extern OpenFiles_T *pDev;
+  ExtendedRequestSense_T ExtendedRequestSense;
+  struct dsreq ds;
+  int Result;
+  int retries = 5;
+  
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(SCSI_ERROR);
+    }
+  
+  memset(&ds, 0, sizeof(struct dsreq));
+  memset(pRequestSense, 0, RequestSenseLength);
+  memset(&ExtendedRequestSense, 0 , sizeof(ExtendedRequestSense_T)); 
+  
+  ds.ds_flags = DSRQ_SENSE|DSRQ_TRACE|DSRQ_PRINT; 
+  /* Timeout */
+  ds.ds_time = 120000;
+  /* Set the cmd */
+  ds.ds_cmdbuf = (caddr_t)CDB;
+  ds.ds_cmdlen = CDB_Length;
+  /* Data buffer for results */
+  ds.ds_databuf = (caddr_t)DataBuffer;
+  ds.ds_datalen = DataBufferLength;
+  /* Sense Buffer */
+  ds.ds_sensebuf = (caddr_t)pRequestSense;
+  ds.ds_senselen = RequestSenseLength;
+  
+  switch (Direction) 
+    {
+    case Input:
+      ds.ds_flags = ds.ds_flags | DSRQ_READ;
+      break;
+    case Output:
+      ds.ds_flags = ds.ds_flags | DSRQ_WRITE;
+      break;
+    }
+  
+  while (--retries > 0) {
+    if (pDev[DeviceFD].devopen == 0)
+      {
+        SCSI_OpenDevice(DeviceFD);
+      }
+    Result = ioctl(pDev[DeviceFD].fd, DS_ENTER, &ds);
+    SCSI_CloseDevice(DeviceFD);
+
+    if (Result < 0)
+      {
+        RET(&ds) = DSRT_DEVSCSI;
+        SCSI_CloseDevice(DeviceFD);
+        return (SCSI_ERROR);
+      }
+    DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
+    dbprintf(("\t\t\tSTATUS(%02X) RET(%02X)\n", STATUS(&ds), RET(&ds)));
+    switch (STATUS(&ds))
+      {
+      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);
+          }
+      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;
+      }
+  }     
+  return(SCSI_ERROR);
+}
+
+int Tape_Ioctl ( int DeviceFD, int command)
+{
+  extern OpenFiles_T *pDev;
+  struct mtop mtop;
+  
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+  
+  switch (command)
+    {
+    case IOCTL_EJECT:
+      mtop.mt_op = MTUNLOAD;
+      mtop.mt_count = 1;
+      break;
+    default:
+      break;
+    }
+  
+  ioctl(pDev[DeviceFD].fd, MTIOCTOP, &mtop);
+  SCSI_CloseDevice(DeviceFD);
+  return(0);
+}
+
+int Tape_Status( int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  struct mtget mtget;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
+    {
+      dbprintf(("Tape_Status error ioctl %d\n",errno));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
+  
+  switch(mtget.mt_dposn)
+    {
+    case MT_EOT:
+      ret = ret | TAPE_EOT;
+      break;
+    case MT_BOT:
+      ret = ret | TAPE_BOT;
+      break;
+    case MT_WPROT:
+      ret = ret | TAPE_WR_PROT;
+      break;
+    case MT_ONL:
+      ret = TAPE_ONLINE;
+      break;
+    case MT_EOD:
+      break;
+    case MT_FMK:
+      break;
+    default:
+      break;
+    }
+
+  SCSI_CloseDevice(DeviceFD);
+  return(ret); 
+}
+
+int ScanBus(int print)
+{
+  DIR *dir;
+  struct dirent *dirent;
+  extern OpenFiles_T *pDev;
+  extern int errno;
+  int count = 0;
+
+  dir = opendir("/dev/scsi");
+
+  while ((dirent = readdir(dir)) != NULL)
+    {
+      if (strstr(dirent->d_name, "sc") != NULL)
+      {
+        pDev[count].dev = malloc(10);
+        pDev[count].inqdone = 0;
+        sprintf(pDev[count].dev,"/dev/scsi/%s", dirent->d_name);
+        if (OpenDevice(count,pDev[count].dev, "Scan", NULL ))
+          {
+            SCSI_CloseDevice(count);
+            pDev[count].inqdone = 0;
+            
+            if (print)
+              {
+                printf("name /dev/scsi/%s ", dirent->d_name);
+                
+                switch (pDev[count].inquiry->type)
+                  {
+                  case TYPE_DISK:
+                    printf("Disk");
+                    break;
+                  case TYPE_TAPE:
+                    printf("Tape");
+                    break;
+                  case TYPE_PRINTER:
+                    printf("Printer");
+                    break;
+                  case TYPE_PROCESSOR:
+                    printf("Processor");
+                    break;
+                  case TYPE_WORM:
+                    printf("Worm");
+                    break;
+                  case TYPE_CDROM:
+                    printf("Cdrom");
+                    break;
+                  case TYPE_SCANNER:
+                    printf("Scanner");
+                    break;
+                  case TYPE_OPTICAL:
+                    printf("Optical");
+                    break;
+                  case TYPE_CHANGER:
+                    printf("Changer");
+                    break;
+                  case TYPE_COMM:
+                    printf("Comm");
+                    break;
+                  default:
+                    printf("unknown %d",pDev[count].inquiry->type);
+                    break;
+                  }
+                printf("\n");
+              }
+            count++;
+           printf("Count %d\n",count);
+          } else {
+            free(pDev[count].dev);
+            pDev[count].dev=NULL;
+          }
+      }
+    }
+  return 0;
+}
+
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-linux.c b/changer-src/scsi-linux.c
new file mode 100644 (file)
index 0000000..6557fbc
--- /dev/null
@@ -0,0 +1,697 @@
+/*
+ * 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: scsi-linux.c,v 1.1.2.18.4.1.2.5 2003/07/05 16:59:01 ant Exp $
+ *
+ * Interface to execute SCSI commands on Linux
+ *
+ * Copyright (c) Thomas Hepper th@ant.han.de
+ */
+
+
+#include <amanda.h>
+
+#ifdef HAVE_DMALLOC_H
+#include <dmalloc.h>
+#endif
+
+#ifdef HAVE_LINUX_LIKE_SCSI
+
+/*
+#ifdef HAVE_STDIO_H
+*/
+#include <stdio.h>
+/*
+#endif
+*/
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#include <time.h>
+
+#ifdef HAVE_SCSI_SCSI_IOCTL_H
+#include <scsi/scsi_ioctl.h>
+#endif
+
+#ifdef HAVE_SCSI_SG_H
+#include <scsi/sg.h>
+#define LINUX_SG
+#endif
+
+#ifdef HAVE_SYS_MTIO_H
+#include <sys/mtio.h>
+#endif
+
+#include <scsi-defs.h>
+
+
+void SCSI_OS_Version()
+{
+#ifndef lint
+   static char rcsid[] = "$Id: scsi-linux.c,v 1.1.2.18.4.1.2.5 2003/07/05 16:59:01 ant 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)
+    {
+      pDev[DeviceFD].devopen = 0;
+      ret = close(pDev[DeviceFD].fd);
+    }
+
+  return(ret);
+}
+
+/* Open a device to talk to an scsi device, either per ioctl, or
+ * direct writing....
+ * Return:
+ * 0 -> error
+ * 1 -> OK
+ *
+ * TODO:
+ * Define some readable defs for the falgs which can be set (like in the AIX dreiver)
+ *
+ */
+#ifdef LINUX_SG
+int SCSI_OpenDevice(int ip)
+{
+  extern OpenFiles_T *pDev;
+  int DeviceFD;
+  int i;
+  int timeout;
+  int sg_info = 0;                /* Used to get some infos about the sg interface */
+  int ret = 0;                    /* To store return results from ioctl etc */
+  struct stat pstat;
+  char *buffer = NULL ;           /* Will contain the device name after checking */
+  int openmode = O_RDONLY;
+
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### START SCSI_OpenDevice\n");
+  if (pDev[ip].inqdone == 0)
+    {
+      pDev[ip].inqdone = 1;
+      if (strncmp("/dev/sg", pDev[ip].dev, 7) != 0) /* Check if no sg device for an link .... */
+        {
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : checking if %s is a sg device\n", pDev[ip].dev);
+          if (lstat(pDev[ip].dev, &pstat) != -1)
+            {
+              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)
+                    {
+                      DebugPrint(DEBUG_ERROR, SECTION_SCSI,"SCSI_OpenDevice : malloc failed\n");
+                      return(0);
+                    }
+                  memset(buffer, 0, 512);
+                  if (( i = readlink(pDev[ip].dev, buffer, 512)) == -1)
+                    {
+                      if (errno == ENAMETOOLONG )
+                        {
+                        } else {
+                          pDev[ip].SCSI = 0;
+                        }
+                    }
+                  if ( i >= 7)
+                    {
+                      if (strncmp("/dev/sg", buffer, 7) == 0)
+                        {
+                          DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : link points to %s\n", buffer) ;
+                          pDev[ip].flags = 1;
+                        }
+                    }
+                } else {/* S_ISLNK(pstat.st_mode) == 1 */
+                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"No link %s\n", pDev[ip].dev) ;
+                  buffer = stralloc(pDev[ip].dev);
+                }
+            } else {/* lstat(DeviceName, &pstat) != -1 */ 
+              DebugPrint(DEBUG_ERROR, SECTION_SCSI,"can't stat device %s\n", pDev[ip].dev);
+              return(0);
+            }
+        } else {
+          buffer = stralloc(pDev[ip].dev);
+          pDev[ip].flags = 1;
+        }
+      
+      if (pDev[ip].flags == 1)
+        {
+          openmode = O_RDWR;
+        }
+      
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"Try to open %s\n", buffer);
+      if ((DeviceFD = open(buffer, openmode)) > 0)
+        {
+          pDev[ip].avail = 1;
+          pDev[ip].devopen = 1;
+          pDev[ip].fd = DeviceFD;
+        } else {
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice open failed\n");
+          return(0);
+        }
+      
+      DebugPrint(DEBUG_INFO, SECTION_SCSI,"done\n");
+      if ( pDev[ip].flags == 1)
+        {
+          pDev[ip].SCSI = 1;
+        }
+      
+      pDev[ip].dev = stralloc(buffer);
+      if (pDev[ip].SCSI == 1)
+        {
+          if ((ret = ioctl(DeviceFD, SG_GET_VERSION_NUM, &sg_info)) == 0)
+            {
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_VERSION %d\n",sg_info);  
+            } else {
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_VERSION ioctl returned %d\n", ret);
+            }
+
+          if ((ret = ioctl(DeviceFD, SG_GET_RESERVED_SIZE, &sg_info)) == 0)
+            {
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_RESERVED_SIZE %d\n",sg_info);  
+            } else {
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : SG_RESERVED_SIZE ioctl returned %d\n", ret);
+            }
+
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : use SG interface\n");
+          if ((timeout = ioctl(pDev[ip].fd, SG_GET_TIMEOUT)) > 0) 
+            {
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : current timeout %d\n", timeout);
+              timeout = 60000;
+              if (ioctl(pDev[ip].fd, SG_SET_TIMEOUT, &timeout) == 0)
+                {
+                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : timeout set to %d\n", timeout);
+                }
+            }
+          pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+            {
+              if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
+                {
+                  for (i=0;i < 16;i++)
+                    pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+                  for (i=15; i >= 0 && !isalnum(pDev[ip].ident[i]); i--)
+                    {
+                      pDev[ip].ident[i] = '\0';
+                    }
+                  pDev[ip].SCSI = 1;
+
+                 if (pDev[ip].inquiry->type == TYPE_TAPE)
+                 {
+                         pDev[ip].type = stralloc("tape");
+                 }
+
+                 if (pDev[ip].inquiry->type == TYPE_CHANGER)
+                 {
+                         pDev[ip].type = stralloc("changer");
+                 }
+
+                  PrintInquiry(pDev[ip].inquiry);
+                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (1)\n");
+                  return(1);
+                } else {
+                  close(DeviceFD);
+                  free(pDev[ip].inquiry);
+                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (0)\n");
+                  return(0);
+                }
+            } else {
+              pDev[ip].SCSI = 0;
+              pDev[ip].devopen = 0;
+              close(DeviceFD);
+              free(pDev[ip].inquiry);
+              pDev[ip].inquiry = NULL;
+              DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (1)\n");
+              return(1);
+            }
+        } else /* if (pDev[ip].SCSI == 1) */ {  
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"Device not capable for SCSI commands\n");
+          pDev[ip].SCSI = 0;
+          pDev[ip].devopen = 0;
+          close(DeviceFD);
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (1)\n");
+          return(1);
+        }
+    } else { /* if (pDev[ip].inqdone == 0) */
+      if (pDev[ip].flags == 1)
+        {
+          openmode = O_RDWR;
+        } else {
+          openmode = O_RDONLY;
+        }
+      if ((DeviceFD = open(pDev[ip].dev, openmode)) > 0)
+        {
+          pDev[ip].devopen = 1;
+          pDev[ip].fd = DeviceFD;
+          if (pDev[ip].flags == 1)
+            {
+              if ((timeout = ioctl(pDev[ip].fd, SG_GET_TIMEOUT)) > 0) 
+                {
+                  DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : current timeout %d\n", timeout);
+                  timeout = 60000;
+                  if (ioctl(pDev[ip].fd, SG_SET_TIMEOUT, &timeout) == 0)
+                    {
+                      DebugPrint(DEBUG_INFO, SECTION_SCSI,"SCSI_OpenDevice : timeout set to %d\n", timeout);
+                    }
+                }
+            }
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice (1)\n");
+          return(1);
+        } else {
+          DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice open failed\n");
+          return(0);
+        }
+    }
+  DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### STOP SCSI_OpenDevice should not happen !!\n");
+  return(0);
+}
+
+#define SCSI_OFF sizeof(struct sg_header)
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *pRequestSense,
+                        int RequestSenseLength)
+{
+  extern OpenFiles_T *pDev;
+  struct sg_header *psg_header;
+  char *buffer;
+  int osize = 0;
+  int status;
+
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(-1);
+    }
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+  
+/*   if (SCSI_OFF + CDB_Length + DataBufferLength > 4096)  */
+/*     { */
+/*       SCSI_CloseDevice(DeviceFD); */
+/*       DebugPrint(DEBUG_ERROR, SECTION_SCSI,"##### SCSI_ExecuteCommand error, SCSI_OFF + CDB_Length + DataBufferLength > 4096\n"); */
+/*       return(-1); */
+/*     } */
+
+  buffer = (char *)malloc(SCSI_OFF + CDB_Length + DataBufferLength);
+  memset(buffer, 0, SCSI_OFF + CDB_Length + DataBufferLength);
+  memcpy(buffer + SCSI_OFF, CDB, CDB_Length);
+  
+  psg_header = (struct sg_header *)buffer;
+  if (CDB_Length >= 12)
+    {
+      psg_header->twelve_byte = 1;
+    } else {
+      psg_header->twelve_byte = 0;
+    }
+  psg_header->result = 0;
+  psg_header->reply_len = SCSI_OFF + DataBufferLength;
+  
+  switch (Direction)
+    {
+    case Input:
+      osize = 0;
+      break;
+    case Output:
+      osize = DataBufferLength;
+      break;
+    }
+  
+  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 ) 
+    {
+      dbprintf(("SCSI_ExecuteCommand error send \n"));
+      SCSI_CloseDevice(DeviceFD);
+      return(SCSI_ERROR);
+    }
+  
+  memset(buffer, 0, SCSI_OFF + DataBufferLength);
+  status = read(pDev[DeviceFD].fd, buffer, SCSI_OFF + DataBufferLength);
+  memset(pRequestSense, 0, RequestSenseLength);
+  memcpy(pRequestSense, psg_header->sense_buffer, 16);
+  
+  if ( status < 0 || status != SCSI_OFF + DataBufferLength || 
+       psg_header->result ) 
+    { 
+      dbprintf(("SCSI_ExecuteCommand error read \n"));
+      dbprintf(("Status %d (%d) %2X\n", status, SCSI_OFF + DataBufferLength, psg_header->result ));
+      SCSI_CloseDevice(DeviceFD);
+      return(SCSI_ERROR);
+    }
+
+  if (DataBufferLength)
+    {
+       memcpy(DataBuffer, buffer + SCSI_OFF, DataBufferLength);
+    }
+
+  free(buffer);
+  SCSI_CloseDevice(DeviceFD);
+  return(SCSI_OK);
+}
+
+#else
+
+static inline int min(int x, int y)
+{
+  return (x < y ? x : y);
+}
+
+
+static inline int max(int x, int y)
+{
+  return (x > y ? x : y);
+}
+
+int SCSI_OpenDevice(int ip)
+{
+  extern OpenFiles_T *pDev;
+  int DeviceFD;
+  int i;
+
+  if (pDev[ip].inqdone == 0)
+    {
+      pDev[ip].inqdone = 1;
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) > 0)
+        {
+          pDev[ip].avail = 1;
+          pDev[ip].fd = DeviceFD;
+          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 (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
+                {
+                  for (i=0;i < 16 && pDev[ip].inquiry->prod_ident[i] != ' ';i++)
+                    pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+                  pDev[ip].ident[i] = '\0';
+                  pDev[ip].SCSI = 1;
+                  PrintInquiry(pDev[ip].inquiry);
+                  return(1);
+                } else {
+                  free(pDev[ip].inquiry);
+                  close(DeviceFD);
+                  return(0);
+                }
+            } else {
+              close(DeviceFD);
+              free(pDev[ip].inquiry);
+              pDev[ip].inquiry = NULL;
+              return(1);
+            }
+        }
+      return(1); 
+    } else {
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR)) > 0)
+        {
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].devopen = 1;
+          return(1);
+        } else {
+          pDev[ip].devopen = 0;
+          return(0);
+        }
+    }
+}
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *pRequestSense,
+                        int RequestSenseLength)
+{
+  extern OpenFiles_T *pDev;
+  unsigned char *Command;
+  int Zero = 0, Result;
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(SCSI_ERROR);
+    }
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  memset(pRequestSense, 0, RequestSenseLength);
+  switch (Direction)
+    {
+    case Input:
+      Command = (unsigned char *)
+        malloc(8 + max(DataBufferLength, RequestSenseLength));
+      memcpy(&Command[0], &Zero, 4);
+      memcpy(&Command[4], &DataBufferLength, 4);
+      memcpy(&Command[8], CDB, CDB_Length);
+      break;
+    case Output:
+      Command = (unsigned char *)
+        malloc(8 + max(CDB_Length + DataBufferLength, RequestSenseLength));
+      memcpy(&Command[0], &DataBufferLength, 4);
+      memcpy(&Command[4], &Zero, 4);
+      memcpy(&Command[8], CDB, CDB_Length);
+      memcpy(&Command[8 + CDB_Length], DataBuffer, DataBufferLength);
+      break;
+    }
+  
+  DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
+  
+  Result = ioctl(pDev[DeviceFD].fd, SCSI_IOCTL_SEND_COMMAND, Command);
+  if (Result != 0)
+    memcpy(pRequestSense, &Command[8], RequestSenseLength);
+  else if (Direction == Input)
+    memcpy(DataBuffer, &Command[8], DataBufferLength);
+  free(Command);
+  SCSI_CloseDevice(DeviceFD);
+
+  switch(Result)
+    {
+      case 0:
+        return(SCSI_OK);
+        break;
+    default:
+      return(SCSI_SENSE);
+      break;
+    }
+}
+#endif
+
+/*
+ * Send the command to the device with the
+ * ioctl interface
+ */
+int Tape_Ioctl( int DeviceFD, int command)
+{
+  extern OpenFiles_T *pDev;
+  struct mtop mtop;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  switch (command)
+    {
+    case IOCTL_EJECT:
+      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));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
+
+  SCSI_CloseDevice(DeviceFD);
+  return(ret);  
+}
+
+int Tape_Status( int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  struct mtget mtget;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
+  {
+     DebugPrint(DEBUG_ERROR, SECTION_TAPE,"Tape_Status error ioctl %d\n",errno);
+     SCSI_CloseDevice(DeviceFD);
+     return(-1);
+  }
+
+  DebugPrint(DEBUG_INFO, SECTION_TAPE,"ioctl -> mtget.mt_gstat %lX\n",mtget.mt_gstat);
+  if (GMT_ONLINE(mtget.mt_gstat))
+    {
+      ret = TAPE_ONLINE;
+    }
+  
+  if (GMT_BOT(mtget.mt_gstat))
+    {
+      ret = ret | TAPE_BOT;
+    }
+  
+  if (GMT_EOT(mtget.mt_gstat))
+    {
+      ret = ret | TAPE_EOT;
+    }
+  
+  if (GMT_WR_PROT(mtget.mt_gstat))
+    {
+      ret = ret | TAPE_WR_PROT;
+    }
+  
+  if (GMT_DR_OPEN(mtget.mt_gstat))
+    {
+      ret = ret | TAPE_NOT_LOADED;
+    }
+  
+  SCSI_CloseDevice(DeviceFD);
+  return(ret); 
+}
+
+/*
+ * This functions scan all /dev/sg* devices
+ * It opens the device an print the result of the inquiry 
+ *
+ */
+int ScanBus(int print)
+{
+  DIR *dir;
+  struct dirent *dirent;
+  extern OpenFiles_T *pDev;
+  extern int errno;
+  int count = 0;
+
+  dir = opendir("/dev/");
+
+  while ((dirent = readdir(dir)) != NULL)
+    {
+      if (strstr(dirent->d_name, "sg") != NULL)
+      {
+        pDev[count].dev = malloc(10);
+        pDev[count].inqdone = 0;
+        sprintf(pDev[count].dev,"/dev/%s", dirent->d_name);
+        if (OpenDevice(count,pDev[count].dev, "Scan", NULL ))
+          {
+            SCSI_CloseDevice(count);
+            pDev[count].inqdone = 0;
+            
+            if (print)
+              {
+                printf("name /dev/%s ", dirent->d_name);
+                
+                switch (pDev[count].inquiry->type)
+                  {
+                  case TYPE_DISK:
+                    printf("Disk");
+                    break;
+                  case TYPE_TAPE:
+                    printf("Tape");
+                    break;
+                  case TYPE_PRINTER:
+                    printf("Printer");
+                    break;
+                  case TYPE_PROCESSOR:
+                    printf("Processor");
+                    break;
+                  case TYPE_WORM:
+                    printf("Worm");
+                    break;
+                  case TYPE_CDROM:
+                    printf("Cdrom");
+                    break;
+                  case TYPE_SCANNER:
+                    printf("Scanner");
+                    break;
+                  case TYPE_OPTICAL:
+                    printf("Optical");
+                    break;
+                  case TYPE_CHANGER:
+                    printf("Changer");
+                    break;
+                  case TYPE_COMM:
+                    printf("Comm");
+                    break;
+                  default:
+                    printf("unknown %d",pDev[count].inquiry->type);
+                    break;
+                  }
+                printf("\n");
+              }
+            count++;
+           printf("Count %d\n",count);
+          } else {
+            free(pDev[count].dev);
+            pDev[count].dev=NULL;
+          }
+      }
+    }
+  return 0;
+}
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/scsi-proto.c b/changer-src/scsi-proto.c
new file mode 100644 (file)
index 0000000..7aa6f86
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *     $Id: scsi-proto.c,v 1.3 1998/06/13 06:13:25 oliva Exp $
+ *
+ *     scsi-proto.c -- library routines to handle the changer
+ *                     Prototype file for customization
+ *
+ *     Author: Eric Schnoebelen, eric@cirr.com
+ *     interface based on work by: Larry Pyeatt, pyeatt@cs.colostate.edu 
+ *     Copyright: 1997, 1998 Eric Schnoebelen
+ *             
+ *      Michael C. Povel 03.06.98 added dummy for eject_tape
+ */
+
+#include "config.h"
+#include "amanda.h"
+#include "libscsi.h"
+
+#if defined(PROTO_H) 
+
+char *modname = "@(#)" __FILE__
+               ": SCSI support library for the proto scsi interface @(#)";
+
+/* 
+ * this routine checks a specified slot to see if it is empty 
+ */
+int isempty(int fd, int slot)
+{
+    /*
+     * ask the robotics, which have knowledge of the storage elements
+     * if the requested slot is empty.
+     *
+     * nslot available for use when the number of slots needs to be known
+     * to allocate memory.
+     */
+    return (slot_empty? 1 : 0);
+}
+
+int get_clean_state(char *dev)
+{
+   /* Ask the device, if it needs a cleaning */
+    return (needs_cleaning? 1 : 0);
+
+}
+
+/*
+ *
+ */
+void eject_tape(char *tape)
+/* This function ejects the tape from the drive */
+{
+    eject_it;
+}
+
+
+/*
+ * find the first empty slot 
+ */
+int find_empty(int fd)
+{
+    /*
+     * find an empty slot to insert a tape into (if required)
+     *
+     * loop through the list of slots, checking see if it is currently 
+     * occupied.
+     */
+    return (emtpy_slot);
+}
+
+/*
+ * returns one if there is a tape loaded in the drive 
+ */
+int drive_loaded(int fd, int drivenum)
+{
+    /*
+     * check the status of the transport (tape drive).
+     *
+     * return 1 if the drive is occupied, 0 otherwise.
+     */
+    return (occupied ? 1 : 0);
+}
+
+
+/*
+ * unloads the drive, putting the tape in the specified slot 
+ */
+int unload(int fd, int drive, int slot)
+{
+    /*
+     * unload the specified drive into the specified slot
+     * (storage element)
+     */
+    return (success);
+}
+
+
+/*
+ * moves tape from the specified slot into the drive 
+ */
+int load(int fd, int drive, int slot)
+{
+    /*
+     * load the media from the specified element (slot) into the
+     * specified data transfer unit (drive)
+     */
+    return (success);
+}
+
+int get_slot_count(int fd)
+{ 
+
+    /*
+     * return the number of slots in the robot 
+     * to the caller 
+     */
+
+    return number_of_storage_elements;
+}
+
+int get_drive_count(int fd)
+{ 
+
+    /*
+     * retreive the number of data-transfer devices
+     */
+    return number_of_data-transfer_devices;
+}
+
+#endif
diff --git a/changer-src/scsi-solaris.c b/changer-src/scsi-solaris.c
new file mode 100644 (file)
index 0000000..289d1af
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * 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: scsi-solaris.c,v 1.1.2.18.4.1.2.5 2003/01/26 19:20:57 martinea Exp $
+ *
+ * Interface to execute SCSI commands on an Sun Workstation
+ *
+ * Copyright (c) Thomas Hepper th@ant.han.de
+ */
+
+
+#include <amanda.h>
+
+#ifdef HAVE_SOLARIS_LIKE_SCSI
+/*
+#ifdef HAVE_STDIO_H
+*/
+#include <stdio.h>
+/*
+#endif
+*/
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <sys/scsi/impl/uscsi.h>
+
+#include <scsi-defs.h>
+#include <sys/mtio.h>
+
+void SCSI_OS_Version()
+{
+#ifndef lint
+   static char rcsid[] = "$Id: scsi-solaris.c,v 1.1.2.18.4.1.2.5 2003/01/26 19:20:57 martinea Exp $";
+   DebugPrint(DEBUG_INFO, SECTION_INFO, "scsi-os-layer: %s\n",rcsid);
+#endif
+}
+
+int SCSI_OpenDevice(int ip)
+{
+  int DeviceFD;
+  int i;
+  extern OpenFiles_T *pDev;
+
+  if (pDev[ip].inqdone == 0)
+    {
+      pDev[ip].inqdone = 1;
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NONBLOCK)) > 0)
+        {
+          pDev[ip].avail = 1;
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].SCSI = 0;
+          pDev[ip].devopen = 1;
+          pDev[ip].inquiry = (SCSIInquiry_T *)malloc(INQUIRY_SIZE);
+          
+          if (SCSI_Inquiry(ip, pDev[ip].inquiry, INQUIRY_SIZE) == 0)
+            {
+              if (pDev[ip].inquiry->type == TYPE_TAPE || pDev[ip].inquiry->type == TYPE_CHANGER)
+                {
+                  for (i=0;i < 16;i++)
+                    pDev[ip].ident[i] = pDev[ip].inquiry->prod_ident[i];
+                  for (i=15; i >= 0 && !isalnum((int)pDev[ip].ident[i]) ; i--)
+                    {
+                      pDev[ip].ident[i] = '\0';
+                    }
+                  pDev[ip].SCSI = 1;
+
+                 if (pDev[ip].inquiry->type == TYPE_TAPE)
+                 {
+                         pDev[ip].type = stralloc("tape");
+                 }
+
+                 if (pDev[ip].inquiry->type == TYPE_CHANGER)
+                 {
+                         pDev[ip].type = stralloc("changer");
+                 }
+
+                  PrintInquiry(pDev[ip].inquiry);
+                  return(1);
+                } else {
+                  close(DeviceFD);
+                  free(pDev[ip].inquiry);
+                  return(0);
+                }
+            } else {
+              free(pDev[ip].inquiry);
+              pDev[ip].inquiry = NULL;
+              return(1);
+            }
+          return(1);
+        } else {
+          dbprintf(("SCSI_OpenDevice %s failed\n", pDev[ip].dev));
+          return(0);
+        }
+    } else {
+      if ((DeviceFD = open(pDev[ip].dev, O_RDWR| O_NDELAY)) > 0)
+        {
+          pDev[ip].fd = DeviceFD;
+          pDev[ip].devopen = 1;
+          return(1);
+        }
+    }
+  return(0); 
+}
+
+
+int SCSI_CloseDevice(int DeviceFD)
+{
+  int ret;
+  extern OpenFiles_T *pDev;
+
+  ret = close(pDev[DeviceFD].fd);
+  pDev[DeviceFD].devopen = 0;
+  return(ret);
+}
+
+
+int SCSI_ExecuteCommand(int DeviceFD,
+                        Direction_T Direction,
+                        CDB_T CDB,
+                        int CDB_Length,
+                        void *DataBuffer,
+                        int DataBufferLength,
+                        char *pRequestSense,
+                        int RequestSenseLength)
+{
+  extern OpenFiles_T *pDev;
+  extern FILE * debug_file;
+  int ret = 0;
+  int retries = 1;
+  extern int errno;
+  struct uscsi_cmd Command;
+#if 0
+  ExtendedRequestSense_T pExtendedRequestSense;
+#endif
+  static int depth = 0;
+
+  if (pDev[DeviceFD].avail == 0)
+    {
+      return(SCSI_ERROR);
+    }
+  
+  if (depth++ > 2)
+  {
+     --depth;
+     SCSI_CloseDevice(DeviceFD);
+     return SCSI_ERROR;
+  }
+  memset(&Command, 0, sizeof(struct uscsi_cmd));
+  memset(pRequestSense, 0, RequestSenseLength);
+  switch (Direction)
+    {
+    case Input:
+      if (DataBufferLength > 0)
+        memset(DataBuffer, 0, DataBufferLength);
+
+      /* Command.uscsi_flags =  USCSI_READ | USCSI_RQENABLE;    */
+      Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE
+        | USCSI_READ | USCSI_RQENABLE;
+      break;
+    case Output:
+      /* Command.uscsi_flags =  USCSI_WRITE | USCSI_RQENABLE;   */
+      Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE
+        | USCSI_WRITE | USCSI_RQENABLE;
+      break;
+    }
+  /* Set timeout to 5 minutes. */
+  Command.uscsi_timeout = 300;
+  Command.uscsi_cdb = (caddr_t) CDB;
+  Command.uscsi_cdblen = CDB_Length;
+
+  if (DataBufferLength > 0)
+    {  
+      Command.uscsi_bufaddr = DataBuffer;
+      Command.uscsi_buflen = DataBufferLength;
+    } else {
+/*
+ * If there is no data buffer force the direction to write, read with
+ * a null buffer will fail (errno 22)
+ */
+      Command.uscsi_flags = USCSI_DIAGNOSE | USCSI_ISOLATE
+        | USCSI_WRITE | USCSI_RQENABLE;
+   }
+
+  Command.uscsi_rqbuf = (caddr_t) pRequestSense;
+  Command.uscsi_rqlen = RequestSenseLength;
+  DecodeSCSI(CDB, "SCSI_ExecuteCommand : ");
+  while (retries > 0)
+  {
+    if (pDev[DeviceFD].devopen == 0)
+      SCSI_OpenDevice(DeviceFD);
+
+    if ((ret = ioctl(pDev[DeviceFD].fd, USCSICMD, &Command)) >= 0)
+    {
+      ret = Command.uscsi_status;
+      break;
+    }
+    dbprintf(("ioctl on %d failed, errno %d, ret %d\n",pDev[DeviceFD].fd, errno, ret));
+#if 0
+    RequestSense(DeviceFD, &pExtendedRequestSense, 0);
+#endif
+    DecodeSense((RequestSense_T *)pRequestSense,
+               "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;
+    }
+}
+
+/*
+ * Send the command to the device with the
+ * ioctl interface
+ */
+int Tape_Ioctl( int DeviceFD, int command)
+{
+  extern OpenFiles_T *pDev;
+  struct mtop mtop;
+  int ret = 0;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+
+  switch (command)
+    {
+    case IOCTL_EJECT:
+      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));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
+
+  SCSI_CloseDevice(DeviceFD);
+  return(ret);  
+}
+
+int Tape_Status( int DeviceFD)
+{
+  extern OpenFiles_T *pDev;
+  struct mtget mtget;
+  int ret = -1;
+
+  if (pDev[DeviceFD].devopen == 0)
+    {
+      SCSI_OpenDevice(DeviceFD);
+    }
+  
+  if (ioctl(pDev[DeviceFD].fd , MTIOCGET, &mtget) != 0)
+    {
+      dbprintf(("Tape_Status error ioctl %d\n",errno));
+      SCSI_CloseDevice(DeviceFD);
+      return(-1);
+    }
+
+  /*
+   * I have no idea what is the meaning of the bits in mt_erreg
+   * I assume that nothing set is tape loaded
+   * 0x2 is no tape online
+   */
+
+  DebugPrint(DEBUG_INFO, SECTION_TAPE, "ioctl result for mt_dsreg (%d)\n", mtget.mt_dsreg);
+  DebugPrint(DEBUG_INFO, SECTION_TAPE, "ioctl result for mt_erreg (%d)\n", mtget.mt_erreg);
+
+  if (mtget.mt_erreg == 0)
+    {
+      ret = ret | TAPE_ONLINE;
+    }
+
+  if (mtget.mt_erreg & 0x2)
+    {
+      ret = ret | TAPE_NOT_LOADED;
+    }
+
+  SCSI_CloseDevice(DeviceFD);
+
+  return(ret); 
+}
+
+int ScanBus(int print)
+{
+       return(-1);
+}
+
+#endif
+/*
+ * Local variables:
+ * indent-tabs-mode: nil
+ * c-file-style: gnu
+ * End:
+ */
diff --git a/changer-src/sense.c b/changer-src/sense.c
new file mode 100644 (file)
index 0000000..37b9803
--- /dev/null
@@ -0,0 +1,851 @@
+#include <amanda.h>
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "scsi-defs.h" 
+/*
+ Handling of Sense codes which are returned from the device
+ At the moment the following status us returned
+ SENSE_ABORT           -> -1 , some strange happend, abort everything
+ SENSE_IGNORE          -> 0 , nothing special, only info
+ SENSE_NO_TAPE         -> 1 , this is for tape devices, not tape online (not used any longer ??)
+ SENSE_RETRY           -> 2 , retry the command
+ SENSE_IES             -> 3 , initialize element status
+ SENSE_TAPE_NOT_LOADED         -> 4 , no tape loaded
+ SENSE_NO                      -> 5 , no sense information
+ SENSE_TAPE_NOT_UNLOADED -> 6 , tape is not ejected
+ SENSE_IES             -> FF , Sense from initialize element status
+ */
+
+       SenseType_T SenseType [] = {
+/*
+ * 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_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_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_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_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_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_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 , -1, 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_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_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_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_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_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_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_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+
+       { "generic", "", TYPE_CHANGER , -1, 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_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_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_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_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_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_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_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+
+       { "DAT AutoChanger", "", TYPE_CHANGER , -1, 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_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, 0xc1, SENSE_IGNORE, "EEPROM Copy 1 bad"},
+       { "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_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"},
+
+/*     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_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, 0x40, 0x84, SENSE_ABORT, "POST soft failure"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x44, 0x80, SENSE_ABORT, "Loader Communications timeout"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x44, 0x81, SENSE_ABORT, "Loader communications UART error or buffer overflow"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x44, 0x86, SENSE_ABORT, "bad status returned from loader"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x44, 0xc3, SENSE_ABORT, "EEPROM both copies bad"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x44, 0xff, SENSE_ABORT, "Unexpected status from test"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x70, SENSE_ABORT, "Cartridge has no home"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x71, SENSE_ABORT, "Loader mechanism problem"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x72, SENSE_ABORT, "Tape drive handle problem"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x73, SENSE_IGNORE, "No cartridge in drive during unload"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x74, SENSE_ABORT, "Loader mechanism problem, after retries"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x75, SENSE_ABORT, "Timeout moving cartridge from drive"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x76, SENSE_ABORT, "Timeout unloading cartridge into slot"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x77, SENSE_ABORT, "Couldn't unlock door after retries"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x78, SENSE_ABORT, "Error during SCAN MAGAZINE"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x79, SENSE_ABORT, "Couldn't lock door after retries"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x80, SENSE_ABORT, "Unexpected door open"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x81, SENSE_ABORT, "Didn't find all expected slots during elevator movement"},
+       { "L500", "", TYPE_CHANGER , SENSE_HARDWARE_ERROR, 0x80, 0x82, SENSE_ABORT, "Cartridge alreay in drive during LOAD CARTRIDGE"},
+       { "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_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, 0x20, 0x0,  SENSE_ABORT, "SCSI invalid opcode"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x21, 0x01, SENSE_ABORT, "Invalid element address"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x00, SENSE_ABORT, "Invalid CDB"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x81, SENSE_ABORT, "Invalid mode on WRITE BUFFER"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x82, SENSE_ABORT, "Invalid drive specified"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x83, SENSE_ABORT, "SEND DIAG Invalid test number"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x86, SENSE_ABORT, "Invalid offset on WRITE BUFFER"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x87, SENSE_ABORT, "Invalid size on WRITE BUFFER"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x89, SENSE_ABORT, "Image data too large on WRITE BUFFER"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x8b, SENSE_ABORT, "Invalid image for CUP"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x8c, SENSE_ABORT, "Non-immediate command during CUP"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x8e, SENSE_ABORT, "Invalid personality for CUP"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x24, 0x8f, SENSE_ABORT, "Bad controller image EDC"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x25, 0x0,  SENSE_ABORT, "Invalid LUN"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x26, 0x0,  SENSE_ABORT, "Parameter list error: invalid field"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x26, 0x01, SENSE_ABORT, "Parameter list error: parameter not supported"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x39, 0x0,  SENSE_ABORT, "Saving parameters not supported"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x3a, 0x81, SENSE_ABORT, "Cleaning Slot empty"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x3a, 0x82, SENSE_ABORT, "Cleaning slot doesn't have a cleaning slot"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x3b, 0x0d, SENSE_ABORT, "Destination element full"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x3b, 0x0e, SENSE_ABORT, "Source slot or drive empty"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x3d, 0x0,  SENSE_ABORT, "SCSI invalid ID message"},
+       { "L500", "", TYPE_CHANGER , SENSE_ILLEGAL_REQUEST, 0x53, 0x0,  SENSE_ABORT, "Media Load/Eject failure"},
+       { "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_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"},
+
+/*     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_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"},
+
+/*
+ * 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_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_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_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_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_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_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 , -1, 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_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_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_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_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_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_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 , -1, 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_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_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_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_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_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_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 , -1, 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_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_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_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_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_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_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"},
+/*
+ * 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_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, 0x0a, 0x00, SENSE_IGNORE, "Error log overflow"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x0a, 0x80, SENSE_IGNORE, "Error log generated"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x37, 0x0,  SENSE_IGNORE, "Rounded parameter"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x38, 0x08, SENSE_IGNORE, "repositioning error"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x44, 0xc1, SENSE_IGNORE, "EEPROM copy1 area bad"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x44, 0xc2, SENSE_IGNORE, "EEPROM copy2 area bad"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x47, 0x00, SENSE_IGNORE, "SCSI parity error"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x48, 0x00, SENSE_IGNORE, "IDE Message received"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x51, 0x00, SENSE_IGNORE, "Erase Failure"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x53, 0x01, SENSE_IGNORE, "Unload Tape failure"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x5b, 0x01, SENSE_IGNORE, "Threshold met"},
+       { "DLT8000", "QUANTUM", TYPE_TAPE , SENSE_RECOVERED_ERROR, 0x5b, 0x02, SENSE_IGNORE, "Log counter at maximum"},
+       { "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_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_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_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_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_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 , -1, 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_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_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"},
+/*
+ * 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_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_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"},
+/*
+ * 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_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_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_CHG_ELEMENT_STATUS, -1, -1, SENSE_IGNORE, "Default for SENSE_CHG_ELEMENT_STATUS"},
+       
+       { "VLS_DLT", "", TYPE_CHANGER, -1, 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_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_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, -1, 0x0, 0x0, SENSE_ABORT, "Nothing Found"},
+/*
+ * Exabyte 85058 Tape
+ */
+       { "EXB-85058HE-0000", "", TYPE_TAPE, SENSE_NOT_READY, 0x4, 0x0, SENSE_RETRY, "Logical Unit not ready, no additional sense"},
+       { "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_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_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"},
+/*
+ * 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_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, 0x85, SENSE_ABORT, "Library door is open"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x85, SENSE_ABORT, "The data cartridge magazine is missing"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x89, SENSE_ABORT, "The library is in CHS Monitor mode"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8C, SENSE_RETRY, "The library is performing a power-on self test"},
+       { "EXB-10e", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8D, SENSE_ABORT, "The library is in LCD mode"},
+       { "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_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_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, -1, 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_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, 0x85, SENSE_ABORT, "Library door is open"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x85, SENSE_ABORT, "The data cartridge magazine is missing"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x89, SENSE_ABORT, "The library is in CHS Monitor mode"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8C, SENSE_RETRY, "The library is performing a power-on self test"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8D, SENSE_ABORT, "The library is in LCD mode"},
+       { "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_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_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, 0x24, 0x00, SENSE_ABORT, "Invalid Invert Field"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x3b, 0x0d, SENSE_ABORT, "Destination element occupied"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x3b, 0x0e, SENSE_ABORT, "Source Element empty"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x3b, 0x87, SENSE_ABORT, "Cartridge stuck in tape"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x3b, 0x90, SENSE_ABORT, "Source cart is loaded inside the tape drive and not accessible"},
+       { "EXB-210", "", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x80, 0x03, SENSE_ABORT, "Source magazine not installed"},
+       { "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_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, 0x3, SENSE_IES, "Label and full status questionable"},
+               { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0x4, SENSE_ABORT, "Tape drive not installed"},
+       { "EXB-210", "", TYPE_CHANGER,  SENSE_CHG_ELEMENT_STATUS, 0x83, 0x7, SENSE_IES, "Full status questionable"},
+       { "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, -1, 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_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, 0x85, SENSE_ABORT, "Library door is open"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x85, SENSE_ABORT, "The data cartridge magazine is missing"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x89, SENSE_ABORT, "The library is in CHS Monitor mode"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8C, SENSE_RETRY, "The library is performing a power-on self test"},
+       { "EXB-230D", "", TYPE_CHANGER, SENSE_NOT_READY, 0x4, 0x8D, SENSE_ABORT, "The library is in LCD mode"},
+       { "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_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_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, -1, 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_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_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, 0x81, 0x4, SENSE_ABORT, "Tape may be broken;of tape is a cleaning tape;or Drive B is broken"},
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x87, 0x0, SENSE_ABORT, "Bad FPROM or invalid device in socket"},
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x87, 0x1, SENSE_ABORT, "FPROM Erase Operation Failed"},
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x87, 0x2, SENSE_ABORT, "FFPROM Write Operation Failed"},
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x1, SENSE_ABORT, "Robot not Initialized"},
+       { "215", "SPECTRA", TYPE_CHANGER, SENSE_HARDWARE_ERROR, 0x85, 0x99, SENSE_ABORT, "Generic Robotics  Error"},
+       { "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_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, 0x24, 0x0, SENSE_ABORT, "Invalid Field in CDB"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x25, 0x0, SENSE_ABORT, "LUN Not Supported"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x26, 0x0, SENSE_ABORT, "Invalid Parameter Field"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x3b, 0xd, SENSE_ABORT, "Medium Destination is full"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x3b, 0xe, SENSE_ABORT, "Medium Source Element is Full"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_ILLEGAL_REQUEST, 0x3d, 0x80, SENSE_ABORT, "Disconnects Must be Allowed"},
+       {"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_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_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, 0x00, SENSE_ABORT, "Unsupported SCSI Command"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x01, SENSE_ABORT, "No Response from SCSI Target"},
+       {"215", "SPECTRA", TYPE_CHANGER, SENSE_VENDOR_SPECIFIC, 0x84, 0x02, SENSE_ABORT, "Check Condition form Target"},
+       {"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, -1, 0x0, 0x0, SENSE_ABORT, "Nothing found for Spectra/215"},
+       
+       { NULL, "", 0x0, -1, 0x0, 0x0, 0x0, ""},
+
+       };
+
+
+void DumpSense()
+{
+       SenseType_T *pwork = (SenseType_T *)&SenseType;
+
+       while (pwork->ident != NULL)    
+       {
+               if (pwork->sense == -1)
+               {
+                       printf("\n");
+               } else {
+                       printf("%s %s %02X %02X %02X %d %s\n",pwork->ident, pwork->vendor,
+                               pwork->sense,
+                               pwork->asc,
+                               pwork->ascq,
+                               pwork->ret,
+                               pwork->text);
+               }
+               pwork++;
+       }
+}
+
+/*
+ * Decode the Sense Key,ASC, ASCQ and device type, and return an action Type.
+ *     type describes the device type as returned by the inquiry command
+ *     ignsense changes the way the ASC/ASCQ values are handled.
+ *      if = 0 the sense key is also used for decoding,
+ *      if > 0 the sense key is ignored in the search, and only ASC/ASCQ will be checked
+ *     sense is the sense key returned by the scsi command
+ *     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)
+{
+       /*
+        * Decode the combination of sense key, ASC, ASCQ and return what to do with this
+        * status
+        * A future extension could be to call direct a function which handles this case
+        *
+        */
+       SenseType_T *pwork = (SenseType_T *)&SenseType;
+       SenseType_T *generic = NULL;
+        int in = 0;
+
+       dbprintf(("Sense2Action START : type(%d), ignsense(%d), sense(%02X), asc(%02X), ascq(%02X)\n",
+               type,
+               ignsense,
+               sense,
+               asc,
+               ascq));
+       
+       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)
+                {
+                       in = 1;
+                } else {
+                       if (in == 1)
+                       {
+                               dbprintf(("Sense2Action       : no match\n"));
+                               break;
+                       }
+                       pwork++;
+                       continue;
+               }
+
+               if (in == 1)
+               {
+                       /* End of definitions for this device */
+                       if (pwork->sense == -1)
+                       {
+                               *text = (char *)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);
+                                       dbprintf(("Sense2Action END(IGN) : match for %s %s  return -> %d/%s\n",
+                                               pwork->ident,
+                                               pwork->vendor,
+                                               pwork->ret,
+                                               *text));        
+                                       return(pwork->ret);
+                               }
+                               pwork++;
+                               continue;
+                       } 
+                       
+                       if (pwork->sense == sense)
+                       {
+                               /* Matching ASC/ASCQ, if yes return the defined result code */
+                               if (pwork->asc ==  asc && pwork->ascq == ascq)
+                               {
+                                       *text = (char *)stralloc(pwork->text);
+                                       dbprintf(("Sense2Action   END : match for %s %s  return -> %d/%s\n",
+                                               pwork->ident,
+                                               pwork->vendor,
+                                               pwork->ret,
+                                               *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)
+                               {
+                                       *text = (char *)stralloc(pwork->text);
+                                       dbprintf(("Sense2Action   END : no match for %s %s  return -> %d/%s\n",
+                                               pwork->ident,
+                                               pwork->vendor,
+                                               pwork->ret,
+                                               *text));        
+                                       return(pwork->ret);
+                               }                       
+                               pwork++;
+                               continue;
+                       }
+                       
+                       pwork++;
+                       continue;
+               }
+               
+               pwork++;
+       }
+
+       /* 
+        * Ok no match found, so lets return the values from the generic table
+        */
+       dbprintf(("Sense2Action generic start :\n"));
+       while (generic->ident != NULL)
+       {         
+               if (generic->sense == -1)
+               {
+                       *text = (char *)stralloc(generic->text);
+                       dbprintf(("Sense2Action generic END : match for %s %s  return -> %d/%s\n",
+                               generic->ident,
+                               generic->vendor,
+                               generic->ret,
+                               *text));        
+                       return(generic->ret);
+               }
+               
+               if (ignsense)
+               {
+                       if (generic->asc ==  asc && generic->ascq == ascq)
+                       {
+                               *text = (char *)stralloc(generic->text);
+                               dbprintf(("Sense2Action generic END(IGN) : match for %s %s  return -> %d/%s\n",
+                                       generic->ident,
+                                       generic->vendor,
+                                       generic->ret,
+                                       *text));        
+                               return(generic->ret);
+                       }
+                       generic++;
+                       continue;
+               } 
+                       
+               if (generic->sense == sense)
+               {
+                       /* Matching ASC/ASCQ, if yes return the defined result code */
+                       if (generic->asc ==  asc && generic->ascq == ascq)
+                       {
+                               *text = (char *)stralloc(generic->text);
+                               dbprintf(("Sense2Action generic END : match for %s %s  return -> %d/%s\n",
+                                       generic->ident,
+                                       generic->vendor,
+                                       generic->ret,
+                                       *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)
+                       {
+                               *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));        
+                               return(generic->ret);
+                       }                       
+                       generic++;
+                       continue;
+               }
+               generic++;
+       }       
+
+       dbprintf(("Sense2Action END:\n"));
+       *text = (char *)stralloc("No match found");
+       return(SENSE_ABORT);
+}
diff --git a/client-src/Makefile.am b/client-src/Makefile.am
new file mode 100644 (file)
index 0000000..43508aa
--- /dev/null
@@ -0,0 +1,106 @@
+# Makefile for Amanda client programs.
+
+INCLUDES =             -I$(top_srcdir)/common-src
+
+lib_LTLIBRARIES =      libamclient.la
+LIB_EXTENSION = la
+
+libexec_PROGRAMS =     amandad calcsize killpgrp rundump runtar amqde selfcheck sendbackup sendsize versionsuffix
+
+sbin_SCRIPTS =         @CLIENT_SCRIPTS_OPT@
+
+libexec_SCRIPTS =      patch-system
+
+if WANT_SAMBA
+samba_sources = findpass.c
+endif
+
+if WANT_RUNTIME_PSEUDO_RELOC
+AM_LDFLAGS = -Wl,-enable-runtime-pseudo-reloc
+endif
+
+libamclient_la_SOURCES=        amandates.c             getfsent.c      \
+                       unctime.c               client_util.c   \
+                       $(samba_sources)
+
+libamclient_la_LDFLAGS = -release $(VERSION)
+
+###
+# 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) \
+       libamclient.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+SUFFIXES =             .sh .pl
+
+.pl:
+                       cat $< > $@
+                       chmod a+x $@
+                       -test -z "$(PERL)" || $(PERL) -c $@
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+# these are used for testing only:
+TEST_PROGS = getfsent
+
+EXTRA_PROGRAMS =       $(TEST_PROGS)
+
+CLEANFILES = *.test.c
+
+EXTRA_SCRIPTS =                amhpfixdevs             amsinixfixdevs
+
+DISTCLEANFILES =       $(EXTRA_SCRIPTS)
+
+EXTRA_DIST =           amhpfixdevs.sh          amsinixfixdevs.sh       \
+                       amandad-krb4.c          sendbackup-krb4.c       \
+                       sendbackup-krb4.h
+
+sendbackup_SOURCES =   sendbackup.c            sendbackup.h    \
+                       sendbackup-dump.c       sendbackup-gnutar.c
+
+noinst_HEADERS =       amandates.h     getfsent.h      findpass.h      \
+                       client_util.h
+
+install-exec-hook:
+       @list="$(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
+if WANT_SETUID_CLIENT
+       @list="calcsize killpgrp rundump runtar amqde"; \
+       for p in $$list; do \
+               if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
+                       pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+                       echo chown root $$pa; \
+                       chown root $$pa; \
+                       echo chmod u+s,o-rwx $$pa; \
+                       chmod u+s,o-rwx $$pa; \
+               else true; \
+               fi; \
+       done
+endif
+
+getfsent_SOURCES = getfsent.test.c
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
diff --git a/client-src/Makefile.in b/client-src/Makefile.in
new file mode 100644 (file)
index 0000000..3e0a368
--- /dev/null
@@ -0,0 +1,854 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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.
+
+
+
+
+SOURCES = $(libamclient_la_SOURCES) amandad.c amqde.c calcsize.c $(getfsent_SOURCES) killpgrp.c rundump.c runtar.c selfcheck.c $(sendbackup_SOURCES) sendsize.c versionsuffix.c
+
+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 = :
+host_triplet = @host@
+libexec_PROGRAMS = amandad$(EXEEXT) calcsize$(EXEEXT) \
+       killpgrp$(EXEEXT) rundump$(EXEEXT) runtar$(EXEEXT) \
+       amqde$(EXEEXT) selfcheck$(EXEEXT) sendbackup$(EXEEXT) \
+       sendsize$(EXEEXT) versionsuffix$(EXEEXT)
+EXTRA_PROGRAMS = $(am__EXEEXT_1)
+subdir = client-src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(srcdir)/patch-system.sh.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 = patch-system.sh
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)"
+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
+@WANT_SAMBA_TRUE@am__objects_1 = findpass.lo
+am_libamclient_la_OBJECTS = amandates.lo getfsent.lo unctime.lo \
+       client_util.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)
+amandad_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamclient.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amqde_SOURCES = amqde.c
+amqde_OBJECTS = amqde.$(OBJEXT)
+amqde_LDADD = $(LDADD)
+amqde_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamclient.$(LIB_EXTENSION) \
+       ../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) \
+       ../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) \
+       ../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) \
+       ../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) \
+       ../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) \
+       ../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) \
+       ../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) \
+       ../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) \
+       ../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) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+libexecSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(libexec_SCRIPTS) $(sbin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/amandad.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amandates.Plo ./$(DEPDIR)/amqde.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/calcsize.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/client_util.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/findpass.Plo ./$(DEPDIR)/getfsent.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/getfsent.test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/killpgrp.Po ./$(DEPDIR)/rundump.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/runtar.Po ./$(DEPDIR)/selfcheck.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/sendbackup-dump.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/sendbackup-gnutar.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/sendbackup.Po ./$(DEPDIR)/sendsize.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/unctime.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/versionsuffix.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libamclient_la_SOURCES) amandad.c amqde.c calcsize.c \
+       $(getfsent_SOURCES) killpgrp.c rundump.c runtar.c selfcheck.c \
+       $(sendbackup_SOURCES) sendsize.c versionsuffix.c
+DIST_SOURCES = $(am__libamclient_la_SOURCES_DIST) amandad.c amqde.c \
+       calcsize.c $(getfsent_SOURCES) killpgrp.c rundump.c runtar.c \
+       selfcheck.c $(sendbackup_SOURCES) sendsize.c versionsuffix.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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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_srcdir)/common-src
+lib_LTLIBRARIES = libamclient.la
+LIB_EXTENSION = la
+sbin_SCRIPTS = @CLIENT_SCRIPTS_OPT@
+libexec_SCRIPTS = patch-system
+@WANT_SAMBA_TRUE@samba_sources = findpass.c
+@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)
+
+libamclient_la_LDFLAGS = -release $(VERSION)
+
+###
+# 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) \
+       libamclient.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+SUFFIXES = .sh .pl
+
+# these are used for testing only:
+TEST_PROGS = getfsent
+CLEANFILES = *.test.c
+EXTRA_SCRIPTS = amhpfixdevs            amsinixfixdevs
+DISTCLEANFILES = $(EXTRA_SCRIPTS)
+EXTRA_DIST = amhpfixdevs.sh            amsinixfixdevs.sh       \
+                       amandad-krb4.c          sendbackup-krb4.c       \
+                       sendbackup-krb4.h
+
+sendbackup_SOURCES = sendbackup.c              sendbackup.h    \
+                       sendbackup-dump.c       sendbackup-gnutar.c
+
+noinst_HEADERS = amandates.h   getfsent.h      findpass.h      \
+                       client_util.h
+
+getfsent_SOURCES = getfsent.test.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .sh .pl .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  client-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  client-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
+patch-system.sh: $(top_builddir)/config.status $(srcdir)/patch-system.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+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="`echo $$p | sed -e 's|^.*/||'`"; \
+           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)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         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
+libamclient.la: $(libamclient_la_OBJECTS) $(libamclient_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(libamclient_la_LDFLAGS) $(libamclient_la_OBJECTS) $(libamclient_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)
+amqde$(EXEEXT): $(amqde_OBJECTS) $(amqde_DEPENDENCIES) 
+       @rm -f amqde$(EXEEXT)
+       $(LINK) $(amqde_LDFLAGS) $(amqde_OBJECTS) $(amqde_LDADD) $(LIBS)
+calcsize$(EXEEXT): $(calcsize_OBJECTS) $(calcsize_DEPENDENCIES) 
+       @rm -f calcsize$(EXEEXT)
+       $(LINK) $(calcsize_LDFLAGS) $(calcsize_OBJECTS) $(calcsize_LDADD) $(LIBS)
+getfsent$(EXEEXT): $(getfsent_OBJECTS) $(getfsent_DEPENDENCIES) 
+       @rm -f getfsent$(EXEEXT)
+       $(LINK) $(getfsent_LDFLAGS) $(getfsent_OBJECTS) $(getfsent_LDADD) $(LIBS)
+killpgrp$(EXEEXT): $(killpgrp_OBJECTS) $(killpgrp_DEPENDENCIES) 
+       @rm -f killpgrp$(EXEEXT)
+       $(LINK) $(killpgrp_LDFLAGS) $(killpgrp_OBJECTS) $(killpgrp_LDADD) $(LIBS)
+rundump$(EXEEXT): $(rundump_OBJECTS) $(rundump_DEPENDENCIES) 
+       @rm -f rundump$(EXEEXT)
+       $(LINK) $(rundump_LDFLAGS) $(rundump_OBJECTS) $(rundump_LDADD) $(LIBS)
+runtar$(EXEEXT): $(runtar_OBJECTS) $(runtar_DEPENDENCIES) 
+       @rm -f runtar$(EXEEXT)
+       $(LINK) $(runtar_LDFLAGS) $(runtar_OBJECTS) $(runtar_LDADD) $(LIBS)
+selfcheck$(EXEEXT): $(selfcheck_OBJECTS) $(selfcheck_DEPENDENCIES) 
+       @rm -f selfcheck$(EXEEXT)
+       $(LINK) $(selfcheck_LDFLAGS) $(selfcheck_OBJECTS) $(selfcheck_LDADD) $(LIBS)
+sendbackup$(EXEEXT): $(sendbackup_OBJECTS) $(sendbackup_DEPENDENCIES) 
+       @rm -f sendbackup$(EXEEXT)
+       $(LINK) $(sendbackup_LDFLAGS) $(sendbackup_OBJECTS) $(sendbackup_LDADD) $(LIBS)
+sendsize$(EXEEXT): $(sendsize_OBJECTS) $(sendsize_DEPENDENCIES) 
+       @rm -f sendsize$(EXEEXT)
+       $(LINK) $(sendsize_LDFLAGS) $(sendsize_OBJECTS) $(sendsize_LDADD) $(LIBS)
+versionsuffix$(EXEEXT): $(versionsuffix_OBJECTS) $(versionsuffix_DEPENDENCIES) 
+       @rm -f versionsuffix$(EXEEXT)
+       $(LINK) $(versionsuffix_LDFLAGS) $(versionsuffix_OBJECTS) $(versionsuffix_LDADD) $(LIBS)
+install-libexecSCRIPTS: $(libexec_SCRIPTS)
+       @$(NORMAL_INSTALL)
+       test -z "$(libexecdir)" || $(mkdir_p) "$(DESTDIR)$(libexecdir)"
+       @list='$(libexec_SCRIPTS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         if test -f $$d$$p; then \
+           f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+           echo " $(libexecSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(libexecdir)/$$f'"; \
+           $(libexecSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(libexecdir)/$$f"; \
+         else :; fi; \
+       done
+
+uninstall-libexecSCRIPTS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(libexec_SCRIPTS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+         echo " rm -f '$(DESTDIR)$(libexecdir)/$$f'"; \
+         rm -f "$(DESTDIR)$(libexecdir)/$$f"; \
+       done
+install-sbinSCRIPTS: $(sbin_SCRIPTS)
+       @$(NORMAL_INSTALL)
+       test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+       @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         if test -f $$d$$p; then \
+           f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+           echo " $(sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+           $(sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \
+         else :; fi; \
+       done
+
+uninstall-sbinSCRIPTS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+         echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+       done
+
+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)/amandates.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amqde.Po@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)/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@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/killpgrp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rundump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runtar.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selfcheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendbackup-dump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendbackup-gnutar.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendbackup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendsize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unctime.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/versionsuffix.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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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 -z "$$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) $(SCRIPTS) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(libexecdir)" "$(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:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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 \
+       install-libexecSCRIPTS install-sbinSCRIPTS
+       @$(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 uninstall-libexecSCRIPTS \
+       uninstall-sbinSCRIPTS
+
+.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-info \
+       install-info-am install-libLTLIBRARIES install-libexecPROGRAMS \
+       install-libexecSCRIPTS install-man install-sbinSCRIPTS \
+       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 uninstall-libexecSCRIPTS \
+       uninstall-sbinSCRIPTS
+
+
+.pl:
+                       cat $< > $@
+                       chmod a+x $@
+                       -test -z "$(PERL)" || $(PERL) -c $@
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+install-exec-hook:
+       @list="$(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
+@WANT_SETUID_CLIENT_TRUE@      @list="calcsize killpgrp rundump runtar amqde"; \
+@WANT_SETUID_CLIENT_TRUE@      for p in $$list; do \
+@WANT_SETUID_CLIENT_TRUE@              if echo "$(libexec_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
+@WANT_SETUID_CLIENT_TRUE@                      pa=$(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+@WANT_SETUID_CLIENT_TRUE@                      echo chown root $$pa; \
+@WANT_SETUID_CLIENT_TRUE@                      chown root $$pa; \
+@WANT_SETUID_CLIENT_TRUE@                      echo chmod u+s,o-rwx $$pa; \
+@WANT_SETUID_CLIENT_TRUE@                      chmod u+s,o-rwx $$pa; \
+@WANT_SETUID_CLIENT_TRUE@              else true; \
+@WANT_SETUID_CLIENT_TRUE@              fi; \
+@WANT_SETUID_CLIENT_TRUE@      done
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
+# 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/client-src/amandad-krb4.c b/client-src/amandad-krb4.c
new file mode 100644 (file)
index 0000000..ac1c092
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991 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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * amandad-krb4.c - The Kerberos4 support bits for amandad.c.
+ */
+
+#include "krb4-security.h"
+
+void transfer_session_key P((void));
+void add_mutual_authenticator P((dgram_t *msg));
+int krb4_security_ok P((struct sockaddr_in *addr,
+                       char *str, unsigned long cksum, char **errstr));
+
+#define KEY_PIPE       3
+
+void transfer_session_key()
+{
+    int rc, key_pipe[2];
+    int l, n, s;
+    char *k;
+
+    if(pipe(key_pipe) == -1)
+       error("could not open key pipe: %s", strerror(errno));
+
+    k = (char *)session_key;
+    for(l = 0, n = sizeof(session_key); l < n; l += s) {
+       if ((s = write(key_pipe[1], k + l, n - l)) < 0) {
+           error("error writing to key pipe: %s", strerror(errno));
+       }
+    }
+
+    /* modification by BIS@BBN 4/25/2003:
+     * check that key_pipe[0] is not KEY_PIPE before doing dup2 and
+     * close; otherwise we may inadvertently close KEY_PIPE */
+    aclose(key_pipe[1]);
+    if (key_pipe[0] != KEY_PIPE) {
+       dup2(key_pipe[0], KEY_PIPE);
+       close(key_pipe[0]);
+    }
+}
+
+void add_mutual_authenticator(msg)
+dgram_t *msg;
+{
+    union {
+       char pad[8];            /* minimum size for encryption */
+       uint32_t i;             /* "long" on 32-bit machines */
+    } mutual;
+    int alen, blen;
+    char *s;
+
+    blen = sizeof(mutual);
+    memset(&mutual, 0, blen);
+    mutual.i = htonl(auth_cksum+1);
+
+    encrypt_data(&mutual, blen, session_key);
+
+    s = vstralloc("SECURITY MUTUAL-AUTH ",
+                 bin2astr((unsigned char *)mutual.pad, blen),
+                 "\n", NULL);
+    dgram_cat(msg, s);
+    amfree(s);
+}
diff --git a/client-src/amandad.c b/client-src/amandad.c
new file mode 100644 (file)
index 0000000..dd69e93
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: amandad.c,v 1.32.2.4.4.1.2.6 2003/12/16 22:36:45 martinea Exp $
+ *
+ * handle client-host side of Amanda network communications, including
+ * security checks, execution of the proper service, and acking the
+ * master side
+ */
+
+#include "amanda.h"
+#include "clock.h"
+#include "dgram.h"
+#include "amfeatures.h"
+#include "version.h"
+#include "protocol.h"
+#include "util.h"
+
+#define RECV_TIMEOUT 30
+#define ACK_TIMEOUT  10                /* XXX should be configurable */
+#define MAX_RETRIES   5
+
+/* 
+ * Here are the services that we understand.
+ */
+struct service_s {
+    char *name;
+    int flags;
+#      define NONE             0
+#      define IS_INTERNAL      1       /* service is internal */
+#      define NEED_KEYPIPE     2       /* pass kerberos key in pipe */
+#      define NO_AUTH          4       /* doesn't need authentication */
+} service_table[] = {
+    { "noop",          IS_INTERNAL },
+    { "sendsize",      NONE },
+    { "sendbackup",    NEED_KEYPIPE },
+    { "sendfsinfo",    NONE },
+    { "selfcheck",     NONE },
+    { NULL, NONE }
+};
+
+
+int max_retry_count = MAX_RETRIES;
+int ack_timeout     = ACK_TIMEOUT;
+
+#ifdef KRB4_SECURITY
+#  include "amandad-krb4.c"
+#endif
+
+/* local functions */
+int main P((int argc, char **argv));
+void sendack P((pkt_t *hdr, pkt_t *msg));
+void sendnak P((pkt_t *hdr, pkt_t *msg, char *str));
+void setup_rep P((pkt_t *hdr, pkt_t *msg));
+char *strlower P((char *str));
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    int n;
+    int fd;
+    char *errstr = NULL;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    char *pgm = "amandad";             /* in case argv[0] is not set */
+
+    /* in_msg: The first incoming request.
+       dup_msg: Any other incoming message.
+       out_msg: Standard, i.e. non-repeated, ACK and REP.
+       rej_msg: Any other outgoing message.
+     */
+    pkt_t in_msg, out_msg, rej_msg, dup_msg;
+    char *cmd = NULL, *base = NULL;
+    char *noop_file = NULL;
+    char **vp;
+    char *s;
+    ssize_t s_len;
+    int retry_count, rc, reqlen;
+    int req_pipe[2], rep_pipe[2];
+    int dglen = 0;
+    char number[NUM_STR_SIZE];
+    am_feature_t *our_features = NULL;
+    char *our_feature_string = NULL;
+
+    struct service_s *servp;
+    fd_set insock;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    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 (argc >= 1 && argv != NULL && argv[0] != NULL) {
+       if((pgm = strrchr(argv[0], '/')) != NULL) {
+           pgm++;
+       } else {
+           pgm = argv[0];
+       }
+    }
+
+    set_pname(pgm);
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
+
+#ifdef FORCE_USERID
+
+    /* we'd rather not run as root */
+    if(geteuid() == 0) {
+#ifdef KRB4_SECURITY
+        if(client_uid == (uid_t) -1) {
+           error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+       }
+
+        /*
+        * if we're using kerberos security, we'll need to be root in
+        * order to get at the machine's srvtab entry, so we hang on to
+        * some root privledges for now.  We give them up entirely later.
+        */
+       setegid(client_gid);
+       seteuid(client_uid);
+#else
+       initgroups(CLIENT_LOGIN, client_gid);
+       setgid(client_gid);
+       setuid(client_uid);
+#endif  /* KRB4_SECURITY */
+    }
+#endif /* FORCE_USERID */
+
+    /* initialize */
+
+    dbopen();
+    {
+       int db_fd = dbfd();
+       if(db_fd != -1) {
+           dup2(db_fd, 1);
+           dup2(db_fd, 2);
+       }
+    }
+
+    startclock();
+
+    dbprintf(("%s: version %s\n", get_pname(), version()));
+    for(vp = version_info; *vp != NULL; vp++)
+       dbprintf(("%s: %s", debug_prefix(NULL), *vp));
+
+    if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) {
+       dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
+                 debug_prefix(NULL)));
+    }
+
+    our_features = am_init_feature_set();
+    our_feature_string = am_feature_to_string(our_features);
+
+    dgram_zero(&in_msg.dgram); 
+    dgram_socket(&in_msg.dgram, 0);
+
+    dgram_zero(&dup_msg.dgram);
+    dgram_socket(&dup_msg.dgram, 0);
+
+    dgram_zero(&out_msg.dgram);
+    dgram_socket(&out_msg.dgram, 0);
+
+    dgram_zero(&rej_msg.dgram);
+    dgram_socket(&rej_msg.dgram, 0);
+
+    dgram_zero(&rej_msg.dgram);
+    dgram_socket(&rej_msg.dgram, 0);
+
+    /* set up input and response pipes */
+
+#ifdef KRB4_SECURITY
+    if(argc >= 2 && strcmp(argv[1], "-krb4") == 0) {
+       krb4_auth = 1;
+       dbprintf(("%s: using krb4 security\n", debug_prefix(NULL)));
+    }
+    else {
+       dbprintf(("%s: using bsd security\n", debug_prefix(NULL)));
+       krb4_auth = 0;
+    }
+#endif
+
+    /* get request packet and attempt to parse it */
+
+    if((n = dgram_recv(&in_msg.dgram, RECV_TIMEOUT, &in_msg.peer)) <= 0) {
+       char *s;
+
+       if (n == 0) {
+           s = "timeout";
+       } else {
+           s = strerror(errno);
+       }
+       error("error receiving message: %s", s);
+    }
+
+    dbprintf(("%s: got packet:\n--------\n%s--------\n\n",
+             debug_prefix_time(NULL), in_msg.dgram.cur));
+
+    parse_pkt_header(&in_msg);
+    if(in_msg.type != P_REQ && in_msg.type != P_NAK && in_msg.type != P_ACK) {
+       /* XXX */
+       dbprintf(("%s: this is a %s packet, nak'ing it\n", 
+                 debug_prefix_time(NULL),
+                 in_msg.type == P_BOGUS? "bogus" : "unexpected"));
+       if(in_msg.type != P_BOGUS) {
+           parse_errmsg = newvstralloc(parse_errmsg,"unexpected ",
+               in_msg.type == P_ACK? "ack ":
+               in_msg.type == P_REP? "rep ": "",
+               "packet", NULL);
+       }
+       sendnak(&in_msg, &rej_msg, parse_errmsg);
+       dbclose();
+       return 1;
+    }
+    if(in_msg.type != P_REQ) {
+       dbprintf(("%s: strange, this is not a request packet\n",
+                 debug_prefix_time(NULL)));
+       dbclose();
+       return 1;
+    }
+
+    /* lookup service */
+
+    for(servp = service_table; servp->name != NULL; servp++)
+       if(strcmp(servp->name, in_msg.service) == 0) break;
+
+    if(servp->name == NULL) {
+       errstr = newstralloc2(errstr, "unknown service: ", in_msg.service);
+       sendnak(&in_msg, &rej_msg, errstr);
+       dbclose();
+       return 1;
+    }
+
+    if((servp->flags & IS_INTERNAL) != 0) {
+       cmd = stralloc(servp->name);
+    } else {
+       base = newstralloc(base, servp->name);
+       cmd = newvstralloc(cmd, libexecdir, "/", base, versionsuffix(), NULL);
+
+       if(access(cmd, X_OK) == -1) {
+           dbprintf(("%s: execute access to \"%s\" denied\n",
+                     debug_prefix_time(NULL), cmd));
+           errstr = newvstralloc(errstr,
+                                 "service ", base, " unavailable",
+                                 NULL);
+           amfree(base);
+           sendnak(&in_msg, &rej_msg, errstr);
+           dbclose();
+           return 1;
+       }
+       amfree(base);
+    }
+
+    /* everything looks ok initially, send ACK */
+
+    sendack(&in_msg, &out_msg);
+
+    /* 
+     * handle security check: this could take a long time, so it is 
+     * done after the initial ack.
+     */
+
+#if defined(KRB4_SECURITY)
+    /*
+     * we need to be root to access the srvtab file, but only if we started
+     * out that way.
+     */
+    setegid(getgid());
+    seteuid(getuid());
+#endif /* KRB4_SECURITY */
+
+    amfree(errstr);
+    if(!(servp->flags & NO_AUTH)
+       && !security_ok(&in_msg.peer, in_msg.security, in_msg.cksum, &errstr)) {
+       /* XXX log on authlog? */
+       setup_rep(&in_msg, &out_msg);
+       ap_snprintf(out_msg.dgram.cur,
+                   sizeof(out_msg.dgram.data)-out_msg.dgram.len,
+                   "ERROR %s\n", errstr);
+       out_msg.dgram.len = strlen(out_msg.dgram.data);
+       goto send_response;
+    }
+
+#if defined(KRB4_SECURITY) && defined(FORCE_USERID)
+
+    /*
+     * we held on to a root uid earlier for accessing files; since we're
+     * done doing anything requiring root, we can completely give it up.
+     */
+
+    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);
+       setuid(client_uid);
+    }
+
+#endif  /* KRB4_SECURITY && FORCE_USERID */
+
+    dbprintf(("%s: running service \"%s\"\n", debug_prefix_time(NULL), cmd));
+
+    if(strcmp(servp->name, "noop") == 0) {
+       ap_snprintf(number, sizeof(number), "%ld", (long)getpid());
+       noop_file = vstralloc(AMANDA_TMPDIR,
+                             "/",
+                             get_pname(),
+                             ".noop.",
+                             number,
+                             NULL);
+       rep_pipe[0] = open(noop_file, O_RDWR|O_EXCL|O_CREAT);
+       if(rep_pipe[0] < 0) {
+           error("cannot open \"%s\": %s", noop_file, strerror(errno));
+       }
+       (void)unlink(noop_file);
+       s = vstralloc("OPTIONS features=", our_feature_string, ";\n", NULL);
+       s_len = strlen(s);
+       if(fullwrite(rep_pipe[0], s, s_len) != s_len) {
+           error("cannot write %d bytes to %s", s_len, noop_file);
+       }
+       amfree(noop_file);
+       amfree(s);
+       (void)lseek(rep_pipe[0], (off_t)0, SEEK_SET);
+    } else {
+       if(pipe(req_pipe) == -1 || pipe(rep_pipe) == -1)
+           error("pipe: %s", strerror(errno));
+
+       /* spawn first child to handle the request */
+
+       switch(fork()) {
+       case -1: error("could not fork for %s: %s", cmd, strerror(errno));
+
+       default:                /* parent */
+
+           break; 
+
+       case 0:         /* child */
+
+            aclose(req_pipe[1]); 
+            aclose(rep_pipe[0]);
+
+            dup2(req_pipe[0], 0);
+            dup2(rep_pipe[1], 1);
+
+           /* modification by BIS@BBN 4/25/2003:
+            * close these file descriptors BEFORE doing pipe magic
+            * for transferring session key; inside transfer_session_key
+            * is a dup2 to move a pipe to KEY_PIPE, which collided
+            * with req_pipe[0]; when req_pipe[0] was closed after the
+            * call to transfer_session_key, then KEY_PIPE ended up
+            * being closed. */
+            aclose(req_pipe[0]);
+            aclose(rep_pipe[1]);
+
+#ifdef  KRB4_SECURITY
+           transfer_session_key();
+#endif
+
+           /* run service */
+
+           execle(cmd, cmd, NULL, safe_env());
+           error("could not exec %s: %s", cmd, strerror(errno));
+        }
+        amfree(cmd);
+
+        aclose(req_pipe[0]);
+        aclose(rep_pipe[1]);
+
+        /* spawn second child to handle writing the packet to the first child */
+
+        switch(fork()) {
+        case -1: error("could not fork for %s: %s", cmd, strerror(errno));
+
+        default:               /* parent */
+
+           break;
+
+        case 0:                /* child */
+
+            aclose(rep_pipe[0]);
+            reqlen = strlen(in_msg.dgram.cur);
+           if((rc = fullwrite(req_pipe[1], in_msg.dgram.cur, reqlen)) != reqlen) {
+               if(rc < 0) {
+                   error("write to child pipe: %s", strerror(errno));
+               } else {
+                   error("write to child pipe: %d instead of %d", rc, reqlen);
+               }
+           }
+            aclose(req_pipe[1]);
+           exit(0);
+        }
+
+        aclose(req_pipe[1]);
+    }
+
+    setup_rep(&in_msg, &out_msg);
+#ifdef KRB4_SECURITY
+    add_mutual_authenticator(&out_msg.dgram);
+#endif
+
+    while(1) {
+
+       FD_ZERO(&insock);
+       FD_SET(rep_pipe[0], &insock);
+
+       if((servp->flags & IS_INTERNAL) != 0) {
+           n = 0;
+       } else {
+           FD_SET(0, &insock);
+           n = select(rep_pipe[0] + 1,
+                      (SELECT_ARG_TYPE *)&insock,
+                      NULL,
+                      NULL,
+                      NULL);
+       }
+       if(n < 0) {
+           error("select failed: %s", strerror(errno));
+       }
+
+       if(FD_ISSET(rep_pipe[0], &insock)) {
+           if(dglen >= MAX_DGRAM) {
+               error("more than %d bytes received from child", MAX_DGRAM);
+           }
+           rc = read(rep_pipe[0], out_msg.dgram.cur+dglen, MAX_DGRAM-dglen);
+           if(rc <= 0) {
+               if (rc < 0) {
+                   error("reading response pipe: %s", strerror(errno));
+               }
+               break;
+           }
+           dglen += rc;
+       }
+       if(!FD_ISSET(0,&insock))
+           continue;
+
+       if((n = dgram_recv(&dup_msg.dgram, RECV_TIMEOUT, &dup_msg.peer)) <= 0) {
+           char *s;
+
+           if (n == 0) {
+               s = "timeout";
+           } else {
+               s = strerror(errno);
+           }
+           error("error receiving message: %s", s);
+       }
+
+       /* 
+        * Under normal conditions, the master will resend the REQ packet
+        * to be sure we are still alive.  It expects an ACK back right away.
+        *
+        * XXX- Arguably we should parse and security check the new packet, 
+        * only sending an ACK if it passes and the request is identical to
+        * the original one.  However, that's too much work for now. :-) 
+        *
+        * It should suffice to ACK whenever the sender is identical.
+        */
+       dbprintf(("%s: got packet:\n----\n%s----\n\n",
+                 debug_prefix_time(NULL), dup_msg.dgram.data));
+       parse_pkt_header(&dup_msg);
+       if(dup_msg.peer.sin_addr.s_addr == in_msg.peer.sin_addr.s_addr &&
+          dup_msg.peer.sin_port == in_msg.peer.sin_port) {
+           if(dup_msg.type == P_REQ) {
+               dbprintf(("%s: received dup P_REQ packet, ACKing it\n",
+                         debug_prefix_time(NULL)));
+               sendack(&in_msg, &rej_msg);
+           }
+           else {
+               dbprintf(("%s: it is not a P_REQ, ignoring it\n",
+                         debug_prefix_time(NULL)));
+           }
+       }
+       else {
+           dbprintf(("%s: received other packet, NAKing it\n",
+                     debug_prefix_time(NULL)));
+           dbprintf(("  addr: peer %s dup %s, port: peer %d dup %d\n",
+                     inet_ntoa(in_msg.peer.sin_addr),
+                     inet_ntoa(dup_msg.peer.sin_addr),
+                     (int)ntohs(in_msg.peer.sin_port),
+                     (int)ntohs(dup_msg.peer.sin_port)));
+           /* XXX dup_msg filled in? */
+           sendnak(&dup_msg, &rej_msg, "amandad busy");
+       }
+
+    }
+
+    /* XXX reap child?  log if non-zero status?  don't respond if non zero? */
+    /* setup header for out_msg */
+
+    out_msg.dgram.len += dglen;
+    out_msg.dgram.data[out_msg.dgram.len] = '\0';
+    aclose(rep_pipe[0]);
+
+send_response:
+
+    retry_count = 0;
+
+    while(retry_count < max_retry_count) {
+       if(!retry_count)
+           dbprintf(("%s: sending REP packet:\n----\n%s----\n\n",
+                     debug_prefix_time(NULL), out_msg.dgram.data));
+       dgram_send_addr(in_msg.peer, &out_msg.dgram);
+       if((n = dgram_recv(&dup_msg.dgram, ack_timeout, &dup_msg.peer)) <= 0) {
+           char *s;
+
+           if (n == 0) {
+               s = "timeout";
+           } else {
+               s = strerror(errno);
+           }
+
+           /* timed out or error, try again */
+           retry_count++;
+
+           dbprintf(("%s: waiting for ack: %s", debug_prefix_time(NULL), s));
+           if(retry_count < max_retry_count) 
+               dbprintf((", retrying\n"));
+           else 
+               dbprintf((", giving up!\n"));
+
+           continue;
+       }
+       dbprintf(("%s: got packet:\n----\n%s----\n\n",
+                 debug_prefix_time(NULL), dup_msg.dgram.data));
+       parse_pkt_header(&dup_msg);
+
+       
+       if(dup_msg.peer.sin_addr.s_addr == in_msg.peer.sin_addr.s_addr &&
+          dup_msg.peer.sin_port == in_msg.peer.sin_port) {
+           if(dup_msg.type == P_ACK)
+               break;
+           else
+               dbprintf(("%s: it is not an ack\n", debug_prefix_time(NULL)));
+       }
+       else {
+           dbprintf(("%s: weird, it is not a proper ack\n",
+                     debug_prefix_time(NULL)));
+           dbprintf(("  addr: peer %s dup %s, port: peer %d dup %d\n",
+                     inet_ntoa(in_msg.peer.sin_addr),
+                     inet_ntoa(dup_msg.peer.sin_addr),
+                     (int)ntohs(in_msg.peer.sin_port),
+                     (int)ntohs(dup_msg.peer.sin_port)));
+       }               
+    }
+    /* XXX log if retry count exceeded */
+
+    amfree(cmd);
+    amfree(noop_file);
+    amfree(our_feature_string);
+    am_release_feature_set(our_features);
+    our_features = NULL;
+    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
+    }
+
+    dbclose();
+    return 0;
+}
+
+
+/* -------- */
+
+void sendack(hdr, msg)
+pkt_t *hdr;
+pkt_t *msg;
+{
+    /* XXX this isn't very safe either: handle could be bogus */
+    ap_snprintf(msg->dgram.data, sizeof(msg->dgram.data),
+               "Amanda %d.%d ACK HANDLE %s SEQ %d\n",
+               VERSION_MAJOR, VERSION_MINOR,
+               hdr->handle ? hdr->handle : "",
+               hdr->sequence);
+    msg->dgram.len = strlen(msg->dgram.data);
+    dbprintf(("%s: sending ack:\n----\n%s----\n\n",
+             debug_prefix_time(NULL), msg->dgram.data));
+    dgram_send_addr(hdr->peer, &msg->dgram);
+}
+
+void sendnak(hdr, msg, str)
+pkt_t *hdr;
+pkt_t *msg;
+char *str;
+{
+    /* XXX this isn't very safe either: handle could be bogus */
+    ap_snprintf(msg->dgram.data, sizeof(msg->dgram.data),
+               "Amanda %d.%d NAK HANDLE %s SEQ %d\nERROR %s\n",
+               VERSION_MAJOR, VERSION_MINOR,
+               hdr->handle ? hdr->handle : "",
+               hdr->sequence, str ? str : "UNKNOWN");
+
+    msg->dgram.len = strlen(msg->dgram.data);
+    dbprintf(("%s: sending nack:\n----\n%s----\n\n",
+             debug_prefix_time(NULL), msg->dgram.data));
+    dgram_send_addr(hdr->peer, &msg->dgram);
+}
+
+void setup_rep(hdr, msg)
+pkt_t *hdr;
+pkt_t *msg;
+{
+    /* XXX this isn't very safe either: handle could be bogus */
+    ap_snprintf(msg->dgram.data, sizeof(msg->dgram.data),
+               "Amanda %d.%d REP HANDLE %s SEQ %d\n",
+               VERSION_MAJOR, VERSION_MINOR,
+               hdr->handle ? hdr->handle : "",
+               hdr->sequence);
+
+    msg->dgram.len = strlen(msg->dgram.data);
+    msg->dgram.cur = msg->dgram.data + msg->dgram.len;
+
+}
+
+/* -------- */
+
+char *strlower(str)
+char *str;
+{
+    char *s;
+    for(s=str; *s; s++)
+       if(isupper((int)*s)) *s = tolower(*s);
+    return str;
+}
diff --git a/client-src/amandates.c b/client-src/amandates.c
new file mode 100644 (file)
index 0000000..e40a9d6
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * 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: amandates.c,v 1.15.8.1 2003/10/22 17:43:33 martinea Exp $
+ *
+ * manage amandates file, that mimics /etc/dumpdates, but stores
+ * GNUTAR dates
+ */
+
+#include "amanda.h"
+#include "getfsent.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;
+{
+    int rc, level;
+    long ldate;
+    char *line = NULL, *name = NULL;
+    char *s;
+    int ch;
+
+    /* clean up from previous invocation */
+
+    if(amdf != NULL)
+       finish_amandates();
+    if(amandates_list != NULL)
+       free_amandates();
+
+    /* initialize state */
+
+    updated = 0;
+    readonly = !open_readwrite;
+    amdf = NULL;
+    amandates_list = NULL;
+
+    /* open the file */
+
+    if (access(AMANDATES_FILE,F_OK))
+       /* not yet existing */
+       if ( (rc = open(AMANDATES_FILE,(O_CREAT|O_RDWR),0644)) != -1 )
+           /* open/create successfull */
+           aclose(rc);
+
+    if(open_readwrite)
+       amdf = fopen(AMANDATES_FILE, "r+");
+    else
+       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");
+
+    if(amdf == NULL)
+       return 0;
+
+    if(open_readwrite)
+       rc = amflock(fileno(amdf), "amandates");
+    else
+       rc = amroflock(fileno(amdf), "amandates");
+
+    if(rc == -1)
+       error("could not lock %s: %s", AMANDATES_FILE, strerror(errno));
+
+    for(; (line = agets(amdf)) != NULL; free(line)) {
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           continue;                           /* no name field */
+       }
+       name = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';                           /* terminate the name */
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%d %ld", &level, &ldate) != 2) {
+           continue;                           /* no more fields */
+       }
+
+       if(level < 0 || level >= DUMP_LEVELS) {
+           continue;
+       }
+
+       enter_record(name, level, (time_t) ldate);
+    }
+
+    if(ferror(amdf))
+       error("reading %s: %s", AMANDATES_FILE, strerror(errno));
+
+    updated = 0;       /* reset updated flag */
+    return 1;
+}
+
+void finish_amandates()
+{
+    amandates_t *amdp;
+    int level;
+
+    if(amdf == NULL)
+       return;
+
+    if(updated) {
+       if(readonly)
+           error("updated amandates after opening readonly");
+
+       rewind(amdf);
+       for(amdp = amandates_list; amdp != NULL; amdp = amdp->next) {
+           for(level = 0; level < DUMP_LEVELS; level++) {
+               if(amdp->dates[level] == EPOCH) continue;
+               fprintf(amdf, "%s %d %ld\n",
+                       amdp->name, level, (long) amdp->dates[level]);
+           }
+       }
+    }
+
+    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));
+    amdf = NULL;
+}
+
+void free_amandates()
+{
+    amandates_t *amdp, *nextp;
+
+    for(amdp = amandates_list; amdp != NULL; amdp = nextp) {
+       nextp = amdp->next;
+       amfree(amdp->name);
+       amfree(amdp);
+    }
+    amandates_list = NULL;
+}
+
+static amandates_t *lookup(name, import)
+char *name;
+int import;
+{
+    amandates_t *prevp, *amdp, *newp;
+    int rc, level;
+
+    rc = 0;
+
+    for(prevp=NULL,amdp=amandates_list;amdp!=NULL;prevp=amdp,amdp=amdp->next)
+       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;
+}
+
+amandates_t *amandates_lookup(name)
+char *name;
+{
+    return lookup(name, 1);
+}
+
+static void enter_record(name, level, dumpdate)
+char *name;
+int level;
+time_t dumpdate;
+{
+    amandates_t *amdp;
+
+    amdp = lookup(name, 0);
+
+    if(level < 0 || level >= DUMP_LEVELS || dumpdate < amdp->dates[level]) {
+       /* 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]));
+       return;
+    }
+
+    amdp->dates[level] = dumpdate;
+}
+
+
+void amandates_updateone(name, level, dumpdate)
+char *name;
+int level;
+time_t dumpdate;
+{
+    amandates_t *amdp;
+
+    assert(!readonly);
+
+    amdp = lookup(name, 1);
+
+    if(level < 0 || level >= DUMP_LEVELS || dumpdate < amdp->dates[level]) {
+       /* this is not allowed, but we can ignore it */
+       dbprintf(("amandates updateone: %s lev %d: new dumpdate %ld old %ld",
+                 name, level, (long) dumpdate, (long) amdp->dates[level]));
+       return;
+    }
+
+    amdp->dates[level] = dumpdate;
+    updated = 1;
+}
+
+
+/* -------------------------- */
+
+static void import_dumpdates(amdp)
+amandates_t *amdp;
+{
+    char *devname = NULL, *line = NULL, *fname = NULL;
+    int level;
+    time_t dumpdate;
+    FILE *dumpdf;
+    char *s;
+    int ch;
+
+    devname = amname_to_devname(amdp->name);
+
+    if((dumpdf = fopen("/etc/dumpdates", "r")) == NULL) {
+       amfree(devname);
+       return;
+    }
+
+    for(; (line = agets(dumpdf)) != NULL; free(line)) {
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           continue;                           /* no fname field */
+       }
+       fname = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';                           /* terminate fname */
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           continue;                           /* no level field */
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           continue;                           /* no dumpdate field */
+       }
+       dumpdate = unctime(s-1);
+
+       if(strcmp(fname, devname) != 0 || level < 0 || level >= DUMP_LEVELS) {
+           continue;
+       }
+
+       if(dumpdate != -1 && dumpdate > amdp->dates[level]) {
+           if(!readonly) updated = 1;
+           amdp->dates[level] = dumpdate;
+       }
+    }
+    afclose(dumpdf);
+    amfree(devname);
+}
diff --git a/client-src/amandates.h b/client-src/amandates.h
new file mode 100644 (file)
index 0000000..8cf5bba
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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: amandates.h,v 1.3 1998/07/04 00:18:10 oliva Exp $
+ *
+ * interface for amandates file
+ */
+#ifndef AMANDATES_H
+#define AMANDATES_H
+
+#include "amanda.h"
+
+#define DUMP_LEVELS    10      /* XXX should be in amanda.h */
+#define EPOCH          ((time_t)0)
+
+#ifndef AMANDATES_FILE
+#define AMANDATES_FILE "/etc/amandates"
+#endif
+
+typedef struct amandates_s {
+    struct amandates_s *next;
+    char *name;                                /* filesystem name */
+    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));
+
+#endif /* ! AMANDATES_H */
diff --git a/client-src/amhpfixdevs.sh b/client-src/amhpfixdevs.sh
new file mode 100644 (file)
index 0000000..172c503
--- /dev/null
@@ -0,0 +1,66 @@
+
+eval '(exit $?0)' && eval 'exec perl -x -S $0 ${1+"$@"}'
+       & eval 'exec perl -x -S $0 $argv:q'
+               if 0;
+
+#!perl
+
+# Check whether we're on a HP-UX system.
+$uname=`uname`;
+chomp $uname;
+if ( $uname ne "HP-UX" ) {
+       print "Sorry, this script only works for HP-UX systems!\n";
+       exit 1;
+}
+
+# Check whether the user is root.
+$id=`id -un`;
+chomp $id;
+if ( $id ne "root" ) {
+       print "Sorry, this script needs to be run by the superuser!\n";
+       exit 1;
+}
+
+# Determine all volume groups and the logical volumes in these volume groups.
+print "\n\nScanning volume groups...\n";
+open(LV, "vgdisplay -v 2>/dev/null |") or
+  die "$0: unable to open vgdisplay pipe: $!\n";
+while ( <LV> ) {
+       if ( m!^(VG Name\s+/dev/)(.*)! ) {
+               print "\n" if $v;
+               $v = $2;
+               print "The volume group $v contains the following logical volumes:\n";
+       }
+       elsif ( m!(\s+LV Name\s+/dev/$v/)(.*)! ) {
+               print "\t$2\n";
+               $vg{$v} .= "$2 ";
+       }
+}
+close LV or
+  warn "$0: error in closing vgdisplay pipe: $!\n";
+
+# Now fix the device entries for all logical volumes.
+print "\n\nFixing device entries...\n";
+foreach $v ( keys(%vg) ) {
+       foreach $w ( split(/[\s]+/, $vg{$v} ) ) {
+               # First the link for the block device.
+               if ( ! -e "/dev/dsk/${v}_$w" ) {
+                       print "Creating link for /dev/dsk/${v}_$w...";
+                       if ( ! symlink("/dev/$v/$w", "/dev/dsk/${v}_$w") ) {
+                               print "FAILED\n";
+                               next;
+                       }
+                       print "done\n";
+               }
+
+               # Now the link for the raw devive.
+               if ( ! -e "/dev/rdsk/${v}_$w" ) {
+                       print "Creating link for /dev/rdsk/${v}_$w...";
+                       if ( ! symlink("/dev/$v/r$w", "/dev/rdsk/${v}_$w") ) {
+                               print "FAILED\n";
+                               next;
+                       }
+                       print "done\n";
+               }
+       }
+}
diff --git a/client-src/amqde.c b/client-src/amqde.c
new file mode 100644 (file)
index 0000000..731ad09
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ * 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: amqde.c,v 1.1.2.1 2003/10/24 20:38:23 kovert Exp $
+ *
+ * the central header file included by all amanda sources
+ */
+
+#include "amanda.h"
+
+/*
+ * amanda's version of things.
+ */
+#define emalloc alloc
+#define estrdup stralloc
+
+#ifdef USE_STRHASH
+hash_table *parse_exclude_path(char *, char *);
+int should_exclude(hash_table * hash, char *path);
+
+#endif
+
+typedef struct __dirtrax {
+       char *dirname;
+       struct __dirtrax *next;
+}         dirtrax_t;
+
+typedef struct __diretrax_track_ll {
+       dirtrax_t *first, *last;
+}                   dirtrax_ll_t;
+
+int
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+       extern char *optarg;
+       extern int optind;
+
+       int ch;
+       char buf[8192];
+       struct stat top, st;
+       char *path;
+       time_t since = 0;
+       DIR *d;
+       struct dirent *de;
+#ifdef HAVE_UNSIGNED_LONG_LONG
+       unsigned long long total = 0;
+#else
+       unsigned long total = 0;
+#endif
+       dirtrax_ll_t ll;
+       dirtrax_t *trax = NULL, *new, *c;
+       char *exclude_path = NULL;
+       int havesince = 0;
+
+#ifdef USE_STRHASH
+       hash_table *hash = NULL;
+
+#endif
+
+       while ((ch = getopt(argc, argv, "s:x:")) != EOF) {
+               switch (ch) {
+               case 's':
+                       since = atoi(optarg);
+                       havesince = 1;
+                       break;
+               case 'x':
+                       exit(0);
+                       exclude_path = (optarg);
+                       break;
+               default:
+                       fprintf(stderr, "unknown argument \'%c\'", ch);
+                       exit(1);
+               }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+       if (argc == 0) {
+               fprintf(stderr, "must specify a path to dump\n");
+               exit(1);
+       }
+       if (!havesince) {
+               fprintf(stderr, "must specify -s\n");
+               exit(1);
+       }
+       path = argv[0];
+
+#ifdef USE_STRHASH
+       if (exclude_path)
+               hash = parse_exclude_path(path, exclude_path);
+#endif
+
+       if (chdir(path) != 0) {
+               fprintf(stderr, "could not chdir to %s\n", path);
+               exit(1);
+       }
+       if (lstat(".", &top) != 0) {
+               fprintf(stderr, "could not stat %s\n", path);
+               exit(1);
+       }
+       trax = emalloc(sizeof(*trax));
+       trax->dirname = estrdup(".");
+       trax->next = NULL;
+
+       ll.first = ll.last = trax;
+
+       for (new = ll.first; new; new = ll.first) {
+               if (!(d = opendir(new->dirname))) {
+                       goto forcleanup;        /* basically continue; */
+               }
+               /*
+                * skip directories if we cross a device
+                */
+               if (lstat(new->dirname, &st) != 0)
+                       goto forwclosedircleanup;
+               if (top.st_dev != st.st_dev || top.st_rdev != st.st_rdev)
+                       goto forwclosedircleanup;
+
+               while ((de = readdir(d))) {
+                       total += 505;
+                       if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
+                               continue;
+
+                       snprintf(buf, sizeof(buf) - 1, "%s/%s", new->dirname, de->d_name);
+
+#ifdef USE_STRHASH
+                       if (should_exclude(hash, buf))
+                               continue;
+#endif
+
+                       if (lstat(buf, &st) != 0)
+                               continue;
+
+                       if (S_ISDIR(st.st_mode)) {
+                               c = emalloc(sizeof(*c));
+                               c->dirname = estrdup(buf);
+                               c->next = NULL;
+                               ll.last->next = c;
+                               ll.last = c;
+                       } else {
+                               if (st.st_mtime < since && st.st_ctime < since)
+                                       continue;
+                               if ((st.st_blocks * 512) < st.st_size)
+                                       total += (st.st_blocks * 512);
+                               else
+                                       total += st.st_size;
+                               /*
+                                * add in some overhead, these are estimates
+                                * after all
+                                */
+                               total += 505;
+                       }
+               }
+forwclosedircleanup:
+               closedir(d);
+forcleanup:
+               ll.first = new->next;
+               free(new->dirname);
+               free(new);
+       }
+
+       /*
+        * This is dumped out in k so upstream utilies can handle it without
+        * having to handle unsigned long long.  The theory is that if you
+        * need to use these estimates, then you proably have a system that
+        * uses long long.
+        */
+
+#ifdef HAVE_UNSIGNED_LONG_LONG
+       fprintf(stderr, "amqde estimate: %llu kb\n", total/1024);
+#else
+       fprintf(stderr, "amqde estimate: %lu kb\n", total/1024);
+#endif
+       chdir("/");
+
+       return (0);
+}
+
+/*
+ * at the moment, we don't actually parse the include file because it means
+ * implementing globbing, which is a pain in the arse.
+ *
+ * This is quick and dirty, after all.
+ */
+#ifdef USE_STRHASH
+hash_table *
+parse_exclude_path(rootpath, infile)
+       char *rootpath;
+       char *infile;
+{
+       FILE *f;
+       char buf[4096];
+       hash_table *hash;
+
+       return (NULL);
+}
+
+int
+should_exclude(hash, path)
+       hash_table *hash;
+       char *path;
+{
+       return (0);
+}
+
+#endif
diff --git a/client-src/amsinixfixdevs.sh b/client-src/amsinixfixdevs.sh
new file mode 100644 (file)
index 0000000..b4c5a47
--- /dev/null
@@ -0,0 +1,96 @@
+
+eval '(exit $?0)' && eval 'exec perl -x -S $0 ${1+"$@"}'
+       & eval 'exec perl -x -S $0 $argv:q'
+               if 0;
+
+#!perl
+
+# Check whether we're on a SINIX system.
+$uname=`uname`;
+chomp $uname;
+if ( $uname !~ /SINIX/ ) {
+  die("Sorry, this script only works for SINIX systems!\n");
+}
+
+# Check whether the user is root.
+$id=`id -un`;
+chomp $id;
+if ( $id ne "root" ) {
+  die("Sorry, this script needs to be run by the superuser!\n");
+}
+
+# Determine all filesystems currently mounted.
+print "\nDetermining all filesystems currently mounted...\n";
+open(VD, "/usr/bin/mount -p 2>/dev/null |") or
+  die("$0: unable to open mount pipe: $!\n");
+while ( <VD> ) {
+  if ( m!^(/dev/\S*)\s+-\s+(\S+)\s+(vxfs|ufs)\s+! ) {
+    $v = $1;
+    print "Found filesystem $v\n";
+    $vd{$v}++;
+  }
+}
+close VD or
+  warn "$0: error in closing mount pipe: $!\n";
+
+# Determine all virtual disks.
+undef($v);
+print "\nDetermining all virtual disks...\n";
+open(VD, "/sbin/dkconfig -lA 2>/dev/null |") or
+  die("$0: unable to open dkconfig pipe: $!\n");
+while ( <VD> ) {
+  if ( m!^(/dev/\S*):\s+\d+\s+blocks! ) {
+    $v = $1;
+    print "Found virtual disk $v\n";
+    $vd{$v}++;
+  }
+}
+close VD or
+  warn "$0: error in closing dkconfig pipe: $!\n";
+
+# Check whether our target directories are present.
+foreach $d ( "/dev/dsk", "/dev/rdsk" ) {
+  if ( ! -x $d ) {
+    if ( ! mkdir($d, 0755) ) {
+      die("Failed to create directory $d!\n");
+    }
+  }
+}
+
+# Now fix the device entries for all virtual disks.
+print "\nFixing device entries...\n";
+foreach $v ( keys(%vd) ) {
+  # determine the basename of the device
+  ( $name ) = $v =~ m!^/dev/(.+)$!;
+  if ( $name =~ m!/! ) {
+    ( $p, $dev_orig ) = $name =~ m!(.*/)(.*)!;
+  }
+  else {
+    $p = "";
+    $dev_orig = $name;
+  }
+
+  # replace all slashes with _'s
+  $dev_new = $name;
+  $dev_new =~ s!/!_!g;
+
+  # First the link for the block device.
+  if ( ! -e "/dev/dsk/$dev_new" ) {
+    print "Creating link for /dev/dsk/$dev_new...";
+    if ( ! symlink($v, "/dev/dsk/$dev_new") ) {
+      print "FAILED\n";
+      next;
+    }
+    print "done\n";
+  }
+
+  # Now the link for the raw devive.
+  if ( ! -e "/dev/rdsk/$dev_new" ) {
+    print "Creating link for /dev/rdsk/$dev_new...";
+    if ( ! symlink("/dev/${p}r$dev_orig", "/dev/rdsk/$dev_new") ) {
+      print "FAILED\n";
+      next;
+    }
+    print "done\n";
+  }
+}
diff --git a/client-src/calcsize.c b/client-src/calcsize.c
new file mode 100644 (file)
index 0000000..97a032a
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * 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: calcsize.c,v 1.24.2.3.6.1 2002/03/31 21:01:32 jrjackson Exp $
+ *
+ * traverse directory tree to get backup size estimates
+ */
+#include "amanda.h"
+#include "statfs.h"
+
+#define ROUND(n,x)     ((x) + (n) - 1 - (((x) + (n) - 1) % (n)))
+
+/*
+static unsigned long round_function(n, x)
+unsigned long n, x;
+{
+  unsigned long remainder = x % n;
+  if (remainder)
+    x += n-remainder;
+  return x;
+}
+*/
+
+# define ST_BLOCKS(s)  ((s).st_size / 512 + (((s).st_size % 512) ? 1 : 0))
+
+#define        FILETYPES       (S_IFREG|S_IFLNK|S_IFDIR)
+
+typedef struct name_s {
+    struct name_s *next;
+    char *str;
+} Name;
+
+Name *name_stack;
+
+#define MAXDUMPS 10
+
+struct {
+    int max_inode;
+    int total_dirs;
+    int total_files;
+    long total_size;
+} dumpstats[MAXDUMPS];
+
+time_t dumpdate[MAXDUMPS];
+int  dumplevel[MAXDUMPS];
+int ndumps;
+
+void (*add_file) P((int, struct stat *));
+long (*final_size) P((int, char *));
+
+
+int main P((int, char **));
+void traverse_dirs P((char *));
+
+
+void add_file_dump P((int, struct stat *));
+long final_size_dump P((int, char *));
+
+void add_file_gnutar P((int, struct stat *));
+long final_size_gnutar P((int, char *));
+
+void add_file_unknown P((int, struct stat *));
+long final_size_unknown P((int, char *));
+
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+int use_gtar_excl = 0;
+char exclude_string[] = "--exclude=";
+char exclude_list_string[] = "--exclude-list=";
+#endif
+
+int main(argc, argv)
+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;
+    char *d;
+    int l, w;
+    int fd;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("calcsize");
+
+    if (argc < 2) {
+       fprintf(stderr,"Usage: %s file[s]\n",argv[0]);
+       return 1;
+    }
+    for(i=1; i<argc; i++) {
+       if(lstat(argv[i], &finfo) == -1) {
+           fprintf(stderr, "%s: %s\n", argv[i], strerror(errno));
+           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("           gtar           dump\n");
+    printf("total      %-9lu         %-9lu\n",gtar_total,dump_total);
+    return 0;
+#else
+    int i;
+    char *dirname=NULL, *amname=NULL;
+    int fd;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("calcsize");
+
+    safe_cd();
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+#if 0
+    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
+#endif
+
+    argc--, argv++;    /* skip program name */
+
+    /* need at least program, amname, and directory name */
+
+    if(argc < 3) {
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+      usage:
+#endif
+       error("Usage: %s [DUMP|GNUTAR%s] name dir [level date] ...",
+             get_pname(),
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+             " [-X --exclude[-list]=regexp]"
+#else
+             ""
+#endif
+             );
+       return 1;
+    }
+
+    /* parse backup program name */
+
+    if(strcmp(*argv, "DUMP") == 0) {
+#if !defined(DUMP) && !defined(XFSDUMP)
+       error("dump not available on this system");
+       return 1;
+#else
+       add_file = add_file_dump;
+       final_size = final_size_dump;
+#endif
+    }
+    else if(strcmp(*argv, "GNUTAR") == 0) {
+#ifndef GNUTAR
+       error("gnutar not available on this system");
+       return 1;
+#else
+       add_file = add_file_gnutar;
+       final_size = final_size_gnutar;
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+       use_gtar_excl++;
+#endif
+#endif
+    }
+    else {
+       add_file = add_file_unknown;
+       final_size = final_size_unknown;
+    }
+    argc--, argv++;
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+    if ((argc > 1) && strcmp(*argv,"-X") == 0) {
+       char *result = NULL;
+       char *cp = NULL;
+       argv++;
+
+       if (!use_gtar_excl) {
+         error("exclusion specification not supported");
+         return 1;
+       }
+
+       result = stralloc(*argv);
+       if (*result && (cp = strrchr(result,';')))
+           /* delete trailing ; */
+           *cp = 0;
+       if (strncmp(result, exclude_string, sizeof(exclude_string)-1) == 0)
+         add_exclude(result+sizeof(exclude_string)-1);
+       else if (strncmp(result, exclude_list_string,
+                        sizeof(exclude_list_string)-1) == 0) {
+         if (access(result + sizeof(exclude_list_string)-1, R_OK) != 0) {
+           fprintf(stderr,"Cannot open exclude file %s\n",cp+1);
+           use_gtar_excl = 0;
+         } else {
+           add_exclude_file(result + sizeof(exclude_list_string)-1);
+         }
+       } else {
+         amfree(result);
+         goto usage;
+       }
+       amfree(result);
+       argc -= 2;
+       argv++;
+    } else
+       use_gtar_excl = 0;
+#endif
+
+    /* the amanda name can be different from the directory name */
+
+    if (argc > 0) {
+       amname = *argv;
+       argc--, argv++;
+    } else
+       error("missing <name>");
+
+    /* the toplevel directory name to search from */
+    if (argc > 0) {
+       dirname = *argv;
+       argc--, argv++;
+    } else
+       error("missing <dir>");
+
+    /* the dump levels to calculate sizes for */
+
+    ndumps = 0;
+    while(argc >= 2) {
+       if(ndumps < MAXDUMPS) {
+           dumplevel[ndumps] = atoi(argv[0]);
+           dumpdate [ndumps] = (time_t) atol(argv[1]);
+           ndumps++;
+           argc -= 2, argv += 2;
+       }
+    }
+
+    if(argc)
+       error("leftover arg \"%s\", expected <level> and <date>", *argv);
+
+    traverse_dirs(dirname);
+    for(i = 0; i < ndumps; i++) {
+
+       amflock(1, "size");
+
+       lseek(1, (off_t)0, SEEK_END);
+
+       printf("%s %d SIZE %ld\n",
+              amname, dumplevel[i], final_size(i, dirname));
+       fflush(stdout);
+
+       amfunlock(1, "size");
+    }
+
+    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 0;
+#endif
+}
+
+/*
+ * =========================================================================
+ */
+
+#ifndef HAVE_BASENAME
+char *basename(file)
+char *file;
+{
+    char *cp;
+
+    if ( (cp = strrchr(file,'/')) )
+       return cp+1;
+    return file;
+}
+#endif
+
+void push_name P((char *str));
+char *pop_name P((void));
+
+void traverse_dirs(parent_dir)
+char *parent_dir;
+{
+    DIR *d;
+    struct dirent *f;
+    struct stat finfo;
+    char *dirname, *newname = NULL;
+    char *newbase = NULL;
+    dev_t parent_dev = 0;
+    int i;
+    int l;
+
+    if(parent_dir && stat(parent_dir, &finfo) != -1)
+       parent_dev = finfo.st_dev;
+
+    push_name(parent_dir);
+
+    for(dirname = pop_name(); dirname; free(dirname), dirname = pop_name()) {
+
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+       if(use_gtar_excl &&
+          (check_exclude(basename(dirname)) ||
+           check_exclude(dirname)))
+           /* will not be added by gnutar */
+           continue;
+#endif
+
+       if((d = opendir(dirname)) == NULL) {
+           perror(dirname);
+           continue;
+       }
+
+       l = strlen(dirname);
+       if(l > 0 && dirname[l - 1] != '/') {
+           newbase = newstralloc2(newbase, dirname, "/");
+       } else {
+           newbase = newstralloc(newbase, dirname);
+       }
+
+       while((f = readdir(d)) != NULL) {
+           if(is_dot_or_dotdot(f->d_name)) {
+               continue;
+           }
+
+           newname = newstralloc2(newname, newbase, f->d_name);
+           if(lstat(newname, &finfo) == -1) {
+               fprintf(stderr, "%s/%s: %s\n",
+                       dirname, f->d_name, strerror(errno));
+               continue;
+           }
+
+           if(finfo.st_dev != parent_dev) {
+               continue;
+           }
+
+           if((finfo.st_mode & S_IFMT) == S_IFDIR) {
+               push_name(newname);
+           }
+
+           for(i = 0; i < ndumps; i++) {
+               if(finfo.st_ctime >= dumpdate[i]) {
+                   int exclude = 0;
+                   int is_symlink = 0;
+
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+                   exclude = check_exclude(f->d_name);
+#endif
+#ifdef S_IFLNK
+                   is_symlink = ((finfo.st_mode & S_IFMT) == S_IFLNK);
+#endif
+                   if (! exclude &&
+                         /* regular files */
+                       ((finfo.st_mode & S_IFMT) == S_IFREG
+                         /* directories */
+                         || (finfo.st_mode & S_IFMT) == S_IFDIR
+                         /* symbolic links */
+                         || is_symlink)) {
+                       add_file(i, &finfo);
+                   }
+               }
+           }
+       }
+
+#ifdef CLOSEDIR_VOID
+       closedir(d);
+#else
+       if(closedir(d) == -1)
+           perror(dirname);
+#endif
+    }
+    amfree(newbase);
+    amfree(newname);
+}
+
+void push_name(str)
+char *str;
+{
+    Name *newp;
+
+    newp = alloc(sizeof(*newp));
+    newp->str = stralloc(str);
+
+    newp->next = name_stack;
+    name_stack = newp;
+}
+
+char *pop_name()
+{
+    Name *newp = name_stack;
+    char *str;
+
+    if(!newp) return NULL;
+
+    name_stack = newp->next;
+    str = newp->str;
+    amfree(newp);
+    return str;
+}
+
+
+/*
+ * =========================================================================
+ * Backup size calculations for DUMP program
+ *
+ * Given the system-dependent nature of dump, it's impossible to pin this
+ * down accurately.  Luckily, that's not necessary.
+ *
+ * Dump rounds each file up to TP_BSIZE bytes, which is 1k in the BSD dump,
+ * others are unknown.  In addition, dump stores three bitmaps at the
+ * beginning of the dump: a used inode map, a dumped dir map, and a dumped
+ * inode map.  These are sized by the number of inodes in the filesystem.
+ *
+ * We don't take into account the complexities of BSD dump's indirect block
+ * requirements for files with holes, nor the dumping of directories that
+ * are not themselves modified.
+ */
+void add_file_dump(level, sp)
+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;
+}
+
+long final_size_dump(level, topdir)
+int level;
+char *topdir;
+{
+    generic_fs_stats_t stats;
+    int mapsize;
+    char *s;
+
+    /* calculate the map sizes */
+
+    s = stralloc2(topdir, "/.");
+    if(get_fs_stats(s, &stats) == -1) {
+       error("statfs %s: %s", s, strerror(errno));
+    }
+    amfree(s);
+
+    mapsize = (stats.files + 7) / 8;   /* in bytes */
+    mapsize = (mapsize + 1023) / 1024;  /* in kbytes */
+
+    /* the dump contains three maps plus the files */
+
+    return 3*mapsize + dumpstats[level].total_size;
+}
+
+/*
+ * =========================================================================
+ * Backup size calculations for GNUTAR program
+ *
+ * Gnutar's basic blocksize is 512 bytes.  Each file is rounded up to that
+ * size, plus one header block.  Gnutar stores directories' file lists in
+ * incremental dumps - we'll pick up size of the modified dirs here.  These
+ * will be larger than a simple filelist of their contents, but that's ok.
+ *
+ * As with DUMP, we only need a reasonable estimate, not an exact figure.
+ */
+void add_file_gnutar(level, sp)
+int level;
+struct stat *sp;
+{
+    /* the header takes one additional block */
+    dumpstats[level].total_size += ROUND(4,(ST_BLOCKS(*sp) + 1));
+}
+
+long final_size_gnutar(level, topdir)
+int level;
+char *topdir;
+{
+    /* divide by two to get kbytes, rounded up */
+    /* + 4 blocks for security */
+    return (dumpstats[level].total_size + 5) / 2;
+}
+
+/*
+ * =========================================================================
+ * Backup size calculations for unknown backup programs.
+ *
+ * Here we'll just add up the file sizes and output that.
+ */
+
+void add_file_unknown(level, sp)
+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;
+{
+    /* divide by two to get kbytes, rounded up */
+    return (dumpstats[level].total_size + 1) / 2;
+}
diff --git a/client-src/client_util.c b/client-src/client_util.c
new file mode 100644 (file)
index 0000000..557fee6
--- /dev/null
@@ -0,0 +1,696 @@
+/*
+ * 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: client_util.c,v 1.1.2.27 2003/07/02 17:03:32 martinea Exp $
+ *
+ */
+
+#include "client_util.h"
+#include "getfsent.h"
+#include "util.h"
+
+#define MAXMAXDUMPS 16
+
+static char *fixup_relative(name, device)
+char *name;
+char *device;
+{
+    char *newname;
+    if(*name != '/') {
+       char *dirname = amname_to_dirname(device);
+       newname = vstralloc(dirname, "/", name , NULL);
+       amfree(dirname);
+    }
+    else {
+       newname = stralloc(name);
+    }
+    return newname;
+}
+
+
+static char *get_name(diskname, exin, t, n)
+char *diskname, *exin;
+time_t t;
+int n;
+{
+    char number[NUM_STR_SIZE];
+    char *filename;
+    char *ts;
+
+    ts = construct_timestamp(&t);
+    if(n == 0)
+       number[0] = '\0';
+    else
+       ap_snprintf(number, sizeof(number), "%03d", n - 1);
+       
+    filename = vstralloc(get_pname(), ".", diskname, ".", ts, number, ".",
+                        exin, NULL);
+    amfree(ts);
+    return filename;
+}
+
+
+static char *build_name(disk, exin, verbose)
+char *disk, *exin;
+{
+    int n=0, fd=-1;
+    char *filename = NULL;
+    char *afilename = NULL;
+    char *diskname;
+    time_t curtime;
+    char *dbgdir = NULL;
+    char *e = NULL;
+    DIR *d;
+    struct dirent *entry;
+    char *test_name = NULL;
+    int match_len, d_name_len;
+
+
+    time(&curtime);
+    diskname = sanitise_filename(disk);
+
+    dbgdir = stralloc2(AMANDA_TMPDIR, "/");
+    if((d = opendir(AMANDA_TMPDIR)) == NULL) {
+       error("open debug directory \"%s\": %s",
+       AMANDA_TMPDIR, strerror(errno));
+    }
+    test_name = get_name(diskname, exin,
+                        curtime - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);
+    match_len = strlen(get_pname()) + strlen(diskname) + 2;
+    while((entry = readdir(d)) != NULL) {
+       if(is_dot_or_dotdot(entry->d_name)) {
+           continue;
+       }
+       d_name_len = strlen(entry->d_name);
+       if(strncmp(test_name, entry->d_name, match_len) != 0
+          || d_name_len < match_len + 14 + 8
+          || strcmp(entry->d_name+ d_name_len - 7, exin) != 0) {
+           continue;                           /* not one of our files */
+       }
+       if(strcmp(entry->d_name, test_name) < 0) {
+           e = newvstralloc(e, dbgdir, entry->d_name, NULL);
+           (void) unlink(e);                   /* get rid of old file */
+       }
+    }
+    amfree(test_name);
+    amfree(e);
+    closedir(d);
+
+    n=0;
+    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){
+           amfree(afilename);
+           n++;
+       }
+       else {
+           close(fd);
+       }
+       amfree(filename);
+    } while(!afilename && n < 1000);
+
+    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);
+       amfree(afilename);
+    }
+
+    amfree(dbgdir);
+    amfree(diskname);
+
+    return afilename;
+}
+
+
+static int add_exclude(file_exclude, aexc, verbose)
+FILE *file_exclude;
+char *aexc;
+{
+    int l;
+
+    l = strlen(aexc);
+    if(aexc[l-1] == '\n') {
+       aexc[l-1] = '\0';
+       l--;
+    }
+    fprintf(file_exclude, "%s\n", aexc);
+    return 1;
+}
+
+static int add_include(disk, device, file_include, ainc, verbose)
+char *disk, *device;
+FILE *file_include;
+char *ainc;
+{
+    int l;
+    int nb_exp=0;
+
+    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;
+    }
+    else {
+       char *incname = ainc+2;
+       if(strchr(incname, '/')) {
+           fprintf(file_include, "./%s\n", incname);
+           nb_exp++;
+       }
+       else {
+           char *regex;
+           DIR *d;
+           struct dirent *entry;
+
+           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);
+               return 0;
+           }
+           else {
+               while((entry = readdir(d)) != NULL) {
+                   if(is_dot_or_dotdot(entry->d_name)) {
+                       continue;
+                   }
+                   if(match(regex, entry->d_name)) {
+                       fprintf(file_include, "./%s\n", entry->d_name);
+                       nb_exp++;
+                   }
+               }
+               closedir(d);
+           }
+       }
+    }
+    return nb_exp;
+}
+
+char *build_exclude(disk, device, options, verbose)
+char *disk, *device;
+option_t *options;
+int verbose;
+{
+    char *filename;
+    FILE *file_exclude;
+    FILE *exclude;
+    char *aexc = NULL;
+    sle_t *excl;
+    int nb_exclude = 0;
+
+    if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
+    if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
+
+    if(nb_exclude == 0) return NULL;
+
+    if((filename = build_name(disk, "exclude", verbose)) != NULL) {
+       if((file_exclude = fopen(filename,"w")) != NULL) {
+
+           if(options->exclude_file) {
+               for(excl = options->exclude_file->first; excl != NULL;
+                   excl = excl->next) {
+                   add_exclude(file_exclude, excl->name,
+                               verbose && options->exclude_optional == 0);
+               }
+           }
+
+           if(options->exclude_list) {
+               for(excl = options->exclude_list->first; excl != NULL;
+                   excl = excl->next) {
+                   char *exclname = fixup_relative(excl->name, device);
+                   if((exclude = fopen(exclname, "r")) != NULL) {
+                       while ((aexc = agets(exclude)) != NULL) {
+                           add_exclude(file_exclude, aexc,
+                                       verbose && options->exclude_optional == 0);
+                           amfree(aexc);
+                       }
+                       fclose(exclude);
+                   }
+                   else {
+                       dbprintf(("%s: Can't open exclude file '%s': %s\n",
+                                 debug_prefix(NULL),
+                                 exclname,
+                                 strerror(errno)));
+                       if(verbose && (options->exclude_optional == 0 ||
+                                      errno != ENOENT))
+                           printf("ERROR [Can't open exclude file '%s': %s]\n",
+                                  exclname, strerror(errno));
+                   }
+                   amfree(exclname);
+               }
+           }
+            fclose(file_exclude);
+       }
+       else {
+           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));
+       }
+    }
+
+    return filename;
+}
+
+char *build_include(disk, device, options, verbose)
+char *disk;
+char *device;
+option_t *options;
+int verbose;
+{
+    char *filename;
+    FILE *file_include;
+    FILE *include;
+    char *ainc = NULL;
+    sle_t *incl;
+    int nb_include = 0;
+    int nb_exp = 0;
+
+    if(options->include_file) nb_include += options->include_file->nb_element;
+    if(options->include_list) nb_include += options->include_list->nb_element;
+
+    if(nb_include == 0) return NULL;
+
+    if((filename = build_name(disk, "include", verbose)) != NULL) {
+       if((file_include = fopen(filename,"w")) != NULL) {
+
+           if(options->include_file) {
+               for(incl = options->include_file->first; incl != NULL;
+                   incl = incl->next) {
+                   nb_exp += add_include(disk, device, file_include,
+                                 incl->name,
+                                  verbose && options->include_optional == 0);
+               }
+           }
+
+           if(options->include_list) {
+               for(incl = options->include_list->first; incl != NULL;
+                   incl = incl->next) {
+                   char *inclname = fixup_relative(incl->name, device);
+                   if((include = fopen(inclname, "r")) != NULL) {
+                       while ((ainc = agets(include)) != NULL) {
+                           nb_exp += add_include(disk, device,
+                                                 file_include, ainc,
+                                                 verbose && options->include_optional == 0);
+                           amfree(ainc);
+                       }
+                       fclose(include);
+                   }
+                   else {
+                       dbprintf(("%s: Can't open include file '%s': %s\n",
+                                 debug_prefix(NULL),
+                                 inclname,
+                                 strerror(errno)));
+                       if(verbose && (options->include_optional == 0 ||
+                                       errno != ENOENT))
+                           printf("ERROR [Can't open include file '%s': %s]\n",
+                                  inclname, strerror(errno));
+                  }
+                  amfree(inclname);
+               }
+           }
+            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));
+       }
+    }
+       
+    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);
+    }
+
+    return filename;
+}
+
+
+void init_options(options)
+option_t *options;
+{
+    options->str = NULL;
+    options->compress = NO_COMPR;
+    options->no_record = 0;
+    options->bsd_auth = 0;
+    options->createindex = 0;
+#ifdef KRB4_SECURITY
+    options->krb4_auth = 0;
+    options->kencrypt = 0;
+#endif
+    options->exclude_file = NULL;
+    options->exclude_list = NULL;
+    options->include_file = NULL;
+    options->include_list = NULL;
+    options->exclude_optional = 0;
+    options->include_optional = 0;
+}
+
+
+option_t *parse_options(str, disk, device, fs, verbose)
+char *str;
+char *disk, *device;
+am_feature_t *fs;
+int verbose;
+{
+    char *exc;
+    option_t *options;
+    char *p, *tok;
+
+    options = alloc(sizeof(option_t));
+    init_options(options);
+    options->str = stralloc(str);
+
+    p = stralloc(str);
+    tok = strtok(p,";");
+
+    while (tok != NULL) {
+       if(am_has_feature(fs, fe_options_auth)
+          && strncmp(tok, "auth=", 5) == 0) {
+           if(options->bsd_auth
+#ifdef KRB4_SECURITY
+              + options->krb4_auth
+#endif
+              > 0) {
+               dbprintf(("%s: multiple auth option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple auth option]\n");
+               }
+           }
+           if(strcasecmp(tok + 5, "bsd") == 0) {
+               options->bsd_auth = 1;
+           }
+#ifdef KRB4_SECURITY
+           else if(strcasecmp(tok + 5, "krb4") == 0) {
+               options->krb4_auth = 1;
+           }
+#endif
+           else {
+               dbprintf(("%s: unknown auth= value \"%s\"\n",
+                         debug_prefix(NULL), tok + 5));
+               if(verbose) {
+                   printf("ERROR [unknown auth= value \"%s\"]\n", tok + 5);
+               }
+           }
+       }
+       else if(strcmp(tok, "compress-fast") == 0) {
+           if(options->compress != NO_COMPR) {
+               dbprintf(("%s: multiple compress option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple compress option]\n");
+               }
+           }
+           options->compress = COMPR_FAST;
+       }
+       else if(strcmp(tok, "compress-best") == 0) {
+           if(options->compress != NO_COMPR) {
+               dbprintf(("%s: multiple compress option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple compress option]\n");
+               }
+           }
+           options->compress = COMPR_BEST;
+       }
+       else if(strcmp(tok, "srvcomp-fast") == 0) {
+           if(options->compress != NO_COMPR) {
+               dbprintf(("%s: multiple compress option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple compress option]\n");
+               }
+           }
+           options->compress = COMPR_SERVER_FAST;
+       }
+       else if(strcmp(tok, "srvcomp-best") == 0) {
+           if(options->compress != NO_COMPR) {
+               dbprintf(("%s: multiple compress option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple compress option]\n");
+               }
+           }
+           options->compress = COMPR_SERVER_BEST;
+       }
+       else if(strcmp(tok, "no-record") == 0) {
+           if(options->no_record != 0) {
+               dbprintf(("%s: multiple no-record option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple no-record option]\n");
+               }
+           }
+           options->no_record = 1;
+       }
+       else if(strcmp(tok, "bsd-auth") == 0) {
+           if(options->bsd_auth
+#ifdef KRB4_SECURITY
+              + options->krb4_auth
+#endif
+              > 0) {
+               dbprintf(("%s: multiple auth option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple auth option]\n");
+               }
+           }
+           options->bsd_auth = 1;
+       }
+       else if(strcmp(tok, "index") == 0) {
+           if(options->createindex != 0) {
+               dbprintf(("%s: multiple index option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple index option]\n");
+               }
+           }
+           options->createindex = 1;
+       }
+#ifdef KRB4_SECURITY
+       else if(strcmp(tok, "krb4-auth") == 0) {
+           if(options->bsd_auth + options->krb4_auth > 0) {
+               dbprintf(("%s: multiple auth option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple auth option]\n");
+               }
+           }
+           options->krb4_auth = 1;
+       }
+       else if(strcmp(tok, "kencrypt") == 0) {
+           if(options->kencrypt != 0) {
+               dbprintf(("%s: multiple kencrypt option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple kencrypt option]\n");
+               }
+           }
+           options->kencrypt = 1;
+       }
+#endif
+       else if(strcmp(tok, "exclude-optional") == 0) {
+           if(options->exclude_optional != 0) {
+               dbprintf(("%s: multiple exclude-optional option\n", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   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", 
+                         debug_prefix(NULL)));
+               if(verbose) {
+                   printf("ERROR [multiple include-optional option]\n");
+               }
+           }
+           options->include_optional = 1;
+       }
+       else if(strncmp(tok,"exclude-file=", 13) == 0) {
+           exc = &tok[13];
+           options->exclude_file = append_sl(options->exclude_file,exc);
+       }
+       else if(strncmp(tok,"exclude-list=", 13) == 0) {
+           exc = &tok[13];
+           options->exclude_list = append_sl(options->exclude_list, exc);
+       }
+       else if(strncmp(tok,"include-file=", 13) == 0) {
+           exc = &tok[13];
+           options->include_file = append_sl(options->include_file,exc);
+       }
+       else if(strncmp(tok,"include-list=", 13) == 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));
+           if(verbose) {
+               printf("ERROR [unknown option \"%s\"]\n", tok);
+           }
+       }
+       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;
+}
diff --git a/client-src/client_util.h b/client-src/client_util.h
new file mode 100644 (file)
index 0000000..559c957
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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: client_util.h,v 1.1.2.10 2002/04/22 01:54:34 martinea Exp $
+ *
+ */
+
+#ifndef CLIENT_UTIL_H
+#define CLIENT_UTIL_H
+
+#include "amanda.h"
+#include "amfeatures.h"
+#include "sl.h"
+
+typedef struct option_s {
+    char *str;
+    int compress;
+    int no_record;
+    int bsd_auth;
+    int createindex;
+    sl_t *exclude_file;
+    sl_t *exclude_list;
+    sl_t *include_file;
+    sl_t *include_list;
+    int exclude_optional;
+    int include_optional;
+#ifdef KRB4_SECURITY
+    int krb4_auth;
+    int kencrypt;
+#endif
+} 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
+#define COMPR_SERVER_FAST 3
+#define COMPR_SERVER_BEST 4
+
+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 *disk,
+                          char *device,
+                          am_feature_t *fs,
+                          int verbose));
+
+void init_g_options P((g_option_t *g_options));
+g_option_t *parse_g_options P((char *str, int verbose));
+
+#endif
diff --git a/client-src/findpass.c b/client-src/findpass.c
new file mode 100644 (file)
index 0000000..290af67
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * 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: findpass.c,v 1.10.4.1.4.1 2001/08/01 22:36:24 jrjackson Exp $
+ *
+ * Support routines for Amanda SAMBA support
+ */
+
+#include "findpass.h"
+
+/*
+ * Find the Samba password and optional domain for a given disk.
+ * Returns pointers into an alloc-ed area.  The caller should clear them
+ * as soon as reasonable.
+ */
+
+char *findpass(disk, domain)
+char *disk, **domain;
+{
+  FILE *fp;
+  static char *buffer = NULL;
+  char *s, *d, *pw = NULL;
+  int ch;
+
+  *domain = NULL;                              /* just to be sure */
+  if ( (fp = fopen("/etc/amandapass", "r")) ) {
+    amfree(buffer);
+    for (; (buffer = agets(fp)) != NULL; free(buffer)) {
+      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);
+      if (ch && ch != '#') {
+       s[-1] = '\0';                           /* terminate disk name */
+       if ((strcmp(d,"*") == 0) || (strcmp(disk, d) == 0)) {
+         skip_whitespace(s, ch);               /* find start of password */
+         if (ch && ch != '#') {
+           pw = s - 1;                         /* start of password */
+           skip_non_whitespace_cs(s, ch);
+           s[-1] = '\0';                       /* terminate password */
+           pw = stralloc(pw);
+           skip_whitespace(s, ch);             /* find start of domain */
+           if (ch && ch != '#') {
+             *domain = s - 1;                  /* start of domain */
+             skip_non_whitespace_cs(s, ch);
+             s[-1] = '\0';                     /* terminate domain */
+             *domain = stralloc(*domain);
+           }
+         }
+         break;
+       }
+      }
+    }
+    afclose(fp);
+  }
+  return pw;
+}
+
+/* 
+ * Convert an amanda disk-name into a Samba sharename,
+ * optionally for a shell execution (\'s are escaped).
+ * Returns a new name alloc-d that the caller is responsible
+ * for free-ing.
+ */
+char *makesharename(disk, shell)
+char *disk;
+int shell;
+{
+  char *buffer;
+  int buffer_size;
+  char *s;
+  int ch;
+  
+  buffer_size = 2 * strlen(disk) + 1;          /* worst case */
+  buffer = alloc(buffer_size);
+
+  s = buffer;
+  while ((ch = *disk++) != '\0') {
+    if (s >= buffer+buffer_size-2) {           /* room for escape */
+      amfree(buffer);                          /* should never happen */
+      return NULL;                             /* buffer not big enough */
+    }
+    if (ch == '/') {
+      ch = '\\';                               /* convert '/' to '\\' */
+    }
+    if (ch == '\\' && shell) {
+      *s++ = '\\';                             /* add escape for shell */
+    }
+    *s++ = ch;
+  }
+  *s = '\0';                                   /* terminate the share name */
+  return buffer;
+}
+
+/*
+ * find out if the samba sharename specifies both a share
+ * and a target subdirectory or just a share
+ *
+ * the caller is expected to release share & subdir
+ */
+void parsesharename (disk, share, subdir)
+char *disk;
+char **share;
+char **subdir;
+{
+    char *ch=NULL;
+    int slashcnt=0;
+
+    *share = NULL;
+    *subdir = NULL;
+    if (!disk) {
+       return;
+    }
+    *share = stralloc(disk);
+    ch = *share;
+    *subdir = NULL;
+    while (*ch != '\0') {
+       if (*ch == '/') {slashcnt++;}
+       if (slashcnt == 4) {
+           *ch = '\0';
+           *subdir = stralloc(++ch);
+           return;
+       }
+       ch++;
+    }
+}
+
diff --git a/client-src/findpass.h b/client-src/findpass.h
new file mode 100644 (file)
index 0000000..50fd041
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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: findpass.h,v 1.5.8.1 2001/08/01 22:36:24 jrjackson Exp $
+ *
+ * interface to findpass module
+ */
+#ifndef FINDPASS_H
+#define FINDPASS_H
+
+#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));
+
+#endif
diff --git a/client-src/getfsent.c b/client-src/getfsent.c
new file mode 100644 (file)
index 0000000..0c18fd5
--- /dev/null
@@ -0,0 +1,730 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998, 2001 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: getfsent.c,v 1.20.4.1.2.2.2.6 2003/03/17 18:50:11 martinea Exp $
+ *
+ * generic version of code to read fstab
+ */
+
+#include "amanda.h"
+
+#ifdef TEST
+#  include <stdio.h>
+#  include <sys/types.h>
+#  undef P
+#  define P(x) x
+#endif
+
+#include "getfsent.h"
+
+/*
+ * You are in a twisty maze of passages, all alike.
+ * Geesh.
+ */
+
+#if defined(HAVE_FSTAB_H) && !defined(HAVE_MNTENT_H) /* { */
+/*
+** BSD (GETFSENT_BSD)
+*/
+#define GETFSENT_TYPE "BSD (Ultrix, AIX)"
+
+#include <fstab.h>
+
+int open_fstab()
+{
+    return setfsent();
+}
+
+void close_fstab()
+{
+    endfsent();
+}
+
+
+int get_fstab_nextentry(fsent)
+generic_fsent_t *fsent;
+{
+    struct fstab *sys_fsent = getfsent();
+    static char *xfsname = NULL, *xmntdir = NULL;
+    static char *xfstype = NULL, *xmntopts = NULL;
+
+    if(!sys_fsent)
+       return 0;
+    fsent->fsname  = xfsname  = newstralloc(xfsname,  sys_fsent->fs_spec);
+    fsent->mntdir  = xmntdir  = newstralloc(xmntdir,  sys_fsent->fs_file);
+    fsent->freq    = sys_fsent->fs_freq;
+    fsent->passno  = sys_fsent->fs_passno;
+#ifdef STATFS_ULTRIX
+    fsent->fstype  = xfstype  = newstralloc(xfstype,  sys_fsent->fs_name);
+    fsent->mntopts = xmntopts = newstralloc(xmntopts, sys_fsent->fs_opts);
+#else
+#if defined(_AIX)
+    fsent->fstype  = xfstype  = newstralloc(xfstype,  "unknown");
+    fsent->mntopts = xmntopts = newstralloc(xmntopts, sys_fsent->fs_type);
+#else
+    fsent->fstype  = xfstype  = newstralloc(xfstype,  sys_fsent->fs_vfstype);
+    fsent->mntopts = xmntopts = newstralloc(xmntopts, sys_fsent->fs_mntops);
+#endif
+#endif
+    return 1;
+}
+
+#else
+#if defined(HAVE_SYS_VFSTAB_H) /* } { */
+/*
+** SVR4 (GETFSENT_SOLARIS)
+*/
+#define GETFSENT_TYPE "SVR4 (Solaris)"
+
+#include <sys/vfstab.h>
+
+static FILE *fstabf = NULL;
+
+int open_fstab()
+{
+    close_fstab();
+    return (fstabf = fopen(VFSTAB, "r")) != NULL;
+}
+
+void close_fstab()
+{
+    if(fstabf)
+       afclose(fstabf);
+    fstabf = NULL;
+}
+
+int get_fstab_nextentry(fsent)
+generic_fsent_t *fsent;
+{
+    struct vfstab sys_fsent;
+
+    if(getvfsent(fstabf, &sys_fsent) != 0)
+       return 0;
+
+    fsent->fsname  = sys_fsent.vfs_special;
+    fsent->fstype  = sys_fsent.vfs_fstype;
+    fsent->mntdir  = sys_fsent.vfs_mountp;
+    fsent->mntopts = sys_fsent.vfs_mntopts;
+    fsent->freq    = 1;        /* N/A */
+    fsent->passno  = sys_fsent.vfs_fsckpass? atoi(sys_fsent.vfs_fsckpass) : 0;
+    return 1;
+}
+
+#else
+#  if defined(HAVE_MNTENT_H) /* } { */
+
+/*
+** System V.3 (GETFSENT_SVR3, GETFSENT_LINUX)
+*/
+#define GETFSENT_TYPE "SVR3 (NeXTstep, Irix, Linux, HP-UX)"
+
+#include <mntent.h>
+
+#if defined(HAVE_ENDMNTENT)
+#define AMCLOSE_MNTENT(x)      endmntent(x)
+#else
+#define AMCLOSE_MNTENT(x)      fclose(x)
+#endif
+
+static FILE *fstabf1 = NULL;           /* /proc/mounts */
+static FILE *fstabf2 = NULL;           /* MOUNTED */
+static FILE *fstabf3 = NULL;           /* MNTTAB */
+
+int open_fstab()
+{
+    close_fstab();
+#if defined(HAVE_SETMNTENT)
+    fstabf1 = setmntent("/proc/mounts", "r");
+# if defined(MOUNTED)
+    fstabf2 = setmntent(MOUNTED, "r");
+# endif
+# if defined(MNTTAB)
+    fstabf3 = setmntent(MNTTAB, "r");
+# endif
+#else
+# if defined(MNTTAB)
+    fstabf3 = fopen(MNTTAB, "r");
+# endif
+#endif
+    return (fstabf1 != NULL || fstabf2 != NULL || fstabf3 != NULL);
+}
+
+void close_fstab()
+{
+    if (fstabf1) {
+       AMCLOSE_MNTENT(fstabf1);
+       fstabf1 = NULL;
+    }
+    if (fstabf2) {
+       AMCLOSE_MNTENT(fstabf2);
+       fstabf2 = NULL;
+    }
+    if (fstabf3) {
+       AMCLOSE_MNTENT(fstabf3);
+       fstabf3 = NULL;
+    }
+}
+
+int get_fstab_nextentry(fsent)
+generic_fsent_t *fsent;
+{
+    struct mntent *sys_fsent = NULL;
+
+    if(fstabf1) {
+       sys_fsent = getmntent(fstabf1);
+       if(!sys_fsent) {
+           AMCLOSE_MNTENT(fstabf1);
+           fstabf1 = NULL;
+       }
+    }
+    if(!sys_fsent && fstabf2) {
+       sys_fsent = getmntent(fstabf2);
+       if(!sys_fsent) {
+           AMCLOSE_MNTENT(fstabf2);
+           fstabf2 = NULL;
+       }
+    }
+    if(!sys_fsent && fstabf3) {
+       sys_fsent = getmntent(fstabf3);
+       if(!sys_fsent) {
+           AMCLOSE_MNTENT(fstabf3);
+           fstabf3 = NULL;
+       }
+    }
+    if(!sys_fsent) {
+       return 0;
+    }
+
+    fsent->fsname  = sys_fsent->mnt_fsname;
+    fsent->fstype  = sys_fsent->mnt_type;
+    fsent->mntdir  = sys_fsent->mnt_dir;
+    fsent->mntopts = sys_fsent->mnt_opts;
+    fsent->freq    = sys_fsent->mnt_freq;
+    fsent->passno  = sys_fsent->mnt_passno;
+    return 1;
+}
+
+#  else
+#    if defined(HAVE_SYS_MNTTAB_H) || defined(STATFS_SCO_OS5) /* } { */
+
+/* we won't actually include mnttab.h, since it contains nothing useful.. */
+
+#define GETFSENT_TYPE "SVR3 (Interactive UNIX)"
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define FSTAB "/etc/fstab"
+
+static FILE *fstabf = NULL;
+
+int open_fstab()
+{
+    close_fstab();
+    return (fstabf = fopen(FSTAB, "r")) != NULL;
+}
+
+void close_fstab()
+{
+    if(fstabf)
+       afclose(fstabf);
+    fstabf = NULL;
+}
+
+static generic_fsent_t _fsent;
+
+int get_fstab_nextentry(fsent)
+generic_fsent_t *fsent;
+{
+    static char *lfsnam = NULL;
+    static char *opts = NULL;
+    static char *cp = NULL;
+    char *s;
+    int ch;
+
+    amfree(cp);
+    for (; (cp = agets(fstabf)) != NULL; free(cp)) {
+       fsent->fsname = strtok(cp, " \t");
+       if ( fsent->fsname && *fsent->fsname != '#' )
+           break;
+    }
+    if (cp == NULL) return 0;
+
+    fsent->mntdir = strtok((char *)NULL, " \t");
+    fsent->mntopts = strtok((char *)NULL, " \t");
+    if ( *fsent->mntopts != '-' )  {
+       fsent->fstype = fsent->mntopts;
+       fsent->mntopts = "rw";
+    } else {
+       fsent->fstype = "";
+       if (strcmp(fsent->mntopts, "-r") == 0) {
+           fsent->mntopts = "ro";
+       }
+    }
+    if ((s = strchr(fsent->fstype, ',')) != NULL) {
+       *s++ = '\0';
+       strappend(fsent->mntopts, ",");
+       strappend(fsent->mntopts, s);
+    }
+
+    lfsnam = newstralloc(lfsnam, fsent->fstype);
+    s = lfsnam;
+    while((ch = *s++) != '\0') {
+       if(isupper(ch)) ch = tolower(ch);
+       s[-1] = ch;
+    }
+    fsent->fstype = lfsnam;
+
+#define sc "hs"
+    if (strncmp(fsent->fstype, sc, sizeof(sc)-1) == 0)
+       fsent->fstype = "iso9660";
+#undef sc
+
+    fsent->freq = 0;
+    fsent->passno = 0;
+
+    return 1;
+}
+
+#    else
+#      if defined(HAVE_MNTTAB_H) /* } { */
+
+#define GETFSENT_TYPE "SVR3 (SCO UNIX)"
+
+#include <mnttab.h>
+#include <sys/fstyp.h>
+#include <sys/statfs.h>
+
+#define MNTTAB "/etc/mnttab"
+
+/*
+ * If these are defined somewhere please let me know.
+ */
+
+#define MNT_READONLY 0101
+#define MNT_READWRITE 0100
+
+static FILE *fstabf = NULL;
+
+int open_fstab()
+{
+    close_fstab();
+    return (fstabf = fopen(MNTTAB, "r")) != NULL;
+}
+
+void close_fstab()
+{
+    if(fstabf)
+       afclose(fstabf);
+    fstabf = NULL;
+}
+
+static generic_fsent_t _fsent;
+
+int get_fstab_nextentry(fsent)
+generic_fsent_t *fsent;
+{
+    struct statfs fsd;
+    char typebuf[FSTYPSZ];
+    static struct mnttab mnt;
+    char *dp, *ep;
+
+    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
+        && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) {
+       dp = typebuf;
+       ep = fsent->fstype = malloc(strlen(typebuf)+2);
+       while (*dp)
+            *ep++ = tolower(*dp++);
+       *ep=0;
+    }
+
+    if ( mnt.mt_ro_flg == MNT_READONLY ) {
+       fsent->mntopts = "ro";
+    } else {
+       fsent->mntopts = "rw";
+    }
+
+    fsent->freq = 0;
+    fsent->passno = 0;
+    return 1;
+}
+
+#      else /* } { */
+
+#define GETFSENT_TYPE "undefined"
+
+#      endif
+#    endif
+#  endif
+#endif
+#endif /* } */
+
+/*
+ *=====================================================================
+ * Convert either a block or character device name to a character (raw)
+ * device name.
+ *
+ * char *dev2rdev(char *name);
+ *
+ * entry:      name - device name to convert
+ * exit:       matching character device name if found,
+ *             otherwise returns the input
+ *
+ * The input must be an absolute path.
+ *
+ * The exit string area is always an alloc-d area that the caller is
+ * responsible for releasing.
+ *=====================================================================
+ */
+
+static char *dev2rdev(name)
+char *name;
+{
+  char *fname = NULL;
+  struct stat st;
+  char *s;
+  int ch;
+
+  if(stat(name, &st) == 0 && S_ISCHR(st.st_mode)) {
+    /*
+     * If the input is already a character device, just return it.
+     */
+    return stralloc(name);
+  }
+
+  s = name;
+  ch = *s++;
+
+  if(ch == '\0' || ch != '/') return stralloc(name);
+
+  ch = *s++;                                   /* start after first '/' */
+  /*
+   * Break the input path at each '/' and create a new name with an
+   * 'r' before the right part.  For instance:
+   *
+   *   /dev/sd0a -> /dev/rsd0a
+   *   /dev/dsk/c0t0d0s0 -> /dev/rdsk/c0t0d0s0 -> /dev/dsk/rc0t0d0s0
+   */
+  while(ch) {
+    if (ch == '/') {
+      s[-1] = '\0';
+      fname = newvstralloc(fname, name, "/r", s, NULL);
+      s[-1] = ch;
+      if(stat(fname, &st) == 0 && S_ISCHR(st.st_mode)) return fname;
+    }
+    ch = *s++;
+  }
+  amfree(fname);
+  return stralloc(name);                       /* no match */
+}
+
+static int samefile(stats, estat)
+struct stat stats[3], *estat;
+{
+  int i;
+  for(i = 0; i < 3; ++i) {
+    if (stats[i].st_dev == estat->st_dev &&
+       stats[i].st_ino == estat->st_ino)
+      return 1;
+  }
+  return 0;
+}
+
+int search_fstab(name, fsent, check_dev)
+     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.
+   */
+  return 0;
+#else
+  struct stat stats[3];
+  char *fullname = NULL;
+  char *rdev = NULL;
+  int rc;
+
+  if (!name)
+    return 0;
+
+  stats[0].st_dev = stats[1].st_dev = stats[2].st_dev = -1;
+
+  if (stat(name, &stats[0]) == -1)
+    stats[0].st_dev = -1;
+  if (name[0] != '/') {
+    fullname = stralloc2(DEV_PREFIX, name);
+    if (stat(fullname, &stats[1]) == -1)
+      stats[1].st_dev = -1;
+    fullname = newstralloc2(fullname, RDEV_PREFIX, name);
+    if (stat(fullname, &stats[2]) == -1)
+      stats[2].st_dev = -1;
+    amfree(fullname);
+  }
+  else if (stat((rdev = dev2rdev(name)), &stats[1]) == -1)
+    stats[1].st_dev = -1;
+
+  amfree(rdev);
+
+  if (!open_fstab())
+    return 0;
+
+  rc = 0;
+  while(get_fstab_nextentry(fsent)) {
+    struct stat mntstat;
+    struct stat fsstat;
+    struct stat fsrstat;
+    int smnt = -1, sfs = -1, sfsr = -1;
+
+    amfree(rdev);
+
+    if(fsent->mntdir != NULL &&
+       (smnt = stat(fsent->mntdir, &mntstat)) == -1)
+      continue;
+
+    if(fsent->fsname != NULL) {
+      sfs = stat(fsent->fsname, &fsstat);
+      sfsr = stat((rdev = dev2rdev(fsent->fsname)), &fsrstat);
+      if(check_dev == 1 && sfs == -1 && sfsr == -1)
+       continue;
+    }
+
+    if((fsent->mntdir != NULL &&
+       smnt != -1 &&
+        samefile(stats, &mntstat)) || 
+       (fsent->fsname != NULL &&
+       sfs != -1 &&
+        samefile(stats, &fsstat)) ||
+       (fsent->fsname != NULL &&
+       sfsr != -1 &&
+        samefile(stats, &fsrstat))) {
+      rc = 1;
+      break;
+    }
+  }
+  amfree(rdev);
+  close_fstab();
+  return rc;
+#endif /* !IGNORE_FSTAB */
+}
+
+int is_local_fstype(fsent)
+generic_fsent_t *fsent;
+{
+    if(fsent->fstype == NULL)  /* unknown, assume local */
+       return 1;
+
+    /* just eliminate fstypes known to be remote or unsavable */
+
+    return strcmp(fsent->fstype, "nfs") != 0 && /* NFS */
+          strcmp(fsent->fstype, "afs") != 0 && /* Andrew Filesystem */
+          strcmp(fsent->fstype, "swap") != 0 && /* Swap */
+          strcmp(fsent->fstype, "iso9660") != 0 && /* CDROM */
+          strcmp(fsent->fstype, "hs") != 0 && /* CDROM */
+          strcmp(fsent->fstype, "piofs") != 0; /* an AIX printer thing? */
+}
+
+
+char *amname_to_devname(str)
+char *str;
+{
+    generic_fsent_t fsent;
+
+    if(search_fstab(str, &fsent, 1) && fsent.fsname != NULL)
+       str = fsent.fsname;
+    else if(search_fstab(str, &fsent, 0) && fsent.fsname != NULL)
+       str = fsent.fsname;
+
+    return dev2rdev(str);
+}
+
+char *amname_to_dirname(str)
+char *str;
+{
+    generic_fsent_t fsent;
+
+    if(search_fstab(str, &fsent, 1) && fsent.mntdir != NULL)
+       str = fsent.mntdir;
+    else if(search_fstab(str, &fsent, 0) && fsent.mntdir != NULL)
+       str = fsent.mntdir;
+
+    return stralloc(str);
+}
+
+char *amname_to_fstype(str)
+char *str;
+{
+    generic_fsent_t fsent;
+
+    if (!search_fstab(str, &fsent, 1) && !search_fstab(str, &fsent, 0))
+      return stralloc("");
+
+    return stralloc(fsent.fstype);
+}
+
+#ifdef TEST
+
+void
+print_entry(fsent)
+generic_fsent_t *fsent;
+{
+#define nchk(s)        ((s)? (s) : "<NULL>")
+    printf("%-20.20s %-14.14s %-7.7s %4d %5d %s\n",
+          nchk(fsent->fsname), nchk(fsent->mntdir), nchk(fsent->fstype),
+          fsent->freq, fsent->passno, nchk(fsent->mntopts));
+}
+
+int main(argc, argv)
+    int argc;
+    char **argv;
+{
+    generic_fsent_t fsent;
+    int fd;
+    char *s;
+    char *name = NULL;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("getfsent");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    if(!open_fstab()) {
+       fprintf(stderr, "getfsent_test: could not open fstab\n");
+       return 1;
+    }
+
+    printf("getfsent (%s)\n",GETFSENT_TYPE);
+    printf("l/r fsname               mntdir         fstype  freq pass# mntopts\n");
+    while(get_fstab_nextentry(&fsent)) {
+       printf("%c  ",is_local_fstype(&fsent)? 'l' : 'r');
+       print_entry(&fsent);
+    }
+    printf("--------\n");
+
+    close_fstab();
+
+    name = newstralloc(name, "/usr");
+    if(search_fstab(name, &fsent, 1) || search_fstab(name, &fsent, 0)) {
+       printf("Found %s mount for %s:\n",
+              is_local_fstype(&fsent)? "local" : "remote", name);
+       print_entry(&fsent);
+    }
+    else 
+       printf("Mount for %s not found\n", name);
+
+    name = newstralloc(name, "/");
+    if(search_fstab(name, &fsent, 1) || search_fstab(name, &fsent, 0)) {
+       printf("Found %s mount for %s:\n",
+              is_local_fstype(&fsent)? "local" : "remote", name);
+       print_entry(&fsent);
+    }
+    else 
+       printf("Mount for %s not found\n", name);
+
+    name = newstralloc(name, "/");
+    s = amname_to_fstype(name);
+    printf("fstype of `%s': %s\n", name, s);
+    amfree(s);
+    name = newstralloc(name, "/dev/root");
+    s = amname_to_fstype(name);
+    printf("fstype of `%s': %s\n", name, s);
+    amfree(s);
+    name = newstralloc(name, "/usr");
+    s = amname_to_fstype(name);
+    printf("fstype of `%s': %s\n", name, s);
+    amfree(s);
+    name = newstralloc(name, "c0t3d0s0");
+    s = amname_to_fstype(name);
+    printf("fstype of `%s': %s\n", name, s);
+    amfree(s);
+
+    name = newstralloc(name, "/tmp/foo");
+    s = amname_to_devname(name);
+    printf("device of `%s': %s\n", name, s);
+    amfree(s);
+    s = amname_to_dirname(name);
+    printf("dirname of `%s': %s\n", name, s);
+    amfree(s);
+    s = amname_to_fstype(name);
+    printf("fstype of `%s': %s\n", name, s);
+    amfree(s);
+
+    name = newstralloc(name, "./foo");
+    s = amname_to_devname(name);
+    printf("device of `%s': %s\n", name, s);
+    amfree(s);
+    s = amname_to_dirname(name);
+    printf("dirname of `%s': %s\n", name, s);
+    amfree(s);
+    s = amname_to_fstype(name);
+    printf("fstype of `%s': %s\n", name, s);
+    amfree(s);
+
+    while (--argc > 0) {
+       name = newstralloc(name, *++argv);
+       s = amname_to_devname(name);
+       printf("device of `%s': %s\n", name, s);
+       amfree(s);
+       s = amname_to_dirname(name);
+       printf("dirname of `%s': %s\n", name, s);
+       amfree(s);
+       s = amname_to_fstype(name);
+       printf("fstype of `%s': %s\n", name, s);
+       amfree(s);
+    }
+
+    amfree(name);
+
+    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 0;
+}
+
+#endif
diff --git a/client-src/getfsent.h b/client-src/getfsent.h
new file mode 100644 (file)
index 0000000..8bc76d8
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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: getfsent.h,v 1.4.8.1.2.2 2002/10/27 22:58:47 martinea Exp $
+ *
+ * interfaces for obtaining filesystem information
+ */
+#ifndef GETFSENT_H
+#define GETFSENT_H
+
+#ifndef STANDALONE_TEST
+#include "amanda.h"
+#endif
+
+#define FSTAB_RW       "rw"    /* writable filesystem */
+#define FSTAB_RQ       "rq"    /* writable, with quotas */
+#define FSTAB_RO       "ro"    /* read-only filesystem */
+#define FSTAB_SW       "sw"    /* swap device */
+#define FSTAB_XX       "xx"    /* ignore this entry */
+
+typedef struct generic_fsent_s {
+    char *fsname;
+    char *fstype;
+    char *mntdir;
+    char *mntopts;
+    int freq;
+    int passno;
+} generic_fsent_t;
+
+int open_fstab P((void));
+void close_fstab P((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));
+
+char *amname_to_devname P((char *str));
+char *amname_to_dirname P((char *str));
+
+char *amname_to_fstype P((char *str));
+
+#endif /* ! GETFSENT_H */
diff --git a/client-src/killpgrp.c b/client-src/killpgrp.c
new file mode 100644 (file)
index 0000000..9c12141
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * 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: killpgrp.c,v 1.8.4.2.4.1 2002/10/27 14:31:18 martinea Exp $
+ *
+ * if it is the process group leader, it kills all processes in its
+ * process group when it is killed itself.
+ */
+#include "amanda.h"
+#include "version.h"
+
+#ifdef HAVE_GETPGRP
+#ifdef GETPGRP_VOID
+#define AM_GETPGRP() getpgrp()
+#else
+#define AM_GETPGRP() getpgrp(getpid())
+#endif
+#else
+/* we cannot check it, so let us assume it is ok */
+#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(argc, argv)
+int argc;
+char **argv;
+{
+    amwait_t status;
+    int fd;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("killpgrp");
+
+    dbopen();
+    dbprintf(("%s: version %s\n", argv[0], version()));
+
+    if(client_uid == (uid_t) -1) {
+       error("error [cannot find user %s in passwd file]", CLIENT_LOGIN);
+    }
+
+#ifdef FORCE_USERID
+    if (getuid() != client_uid) {
+       error("error [must be invoked by %s]", CLIENT_LOGIN);
+    }
+
+    if (geteuid() != 0) {
+       error("error [must be setuid root]");
+    }
+#endif /* FORCE_USERID */
+
+#if !defined (DONT_SUID_ROOT)
+    setuid(0);
+#endif
+
+    if (AM_GETPGRP() != getpid()) {
+       error("error [must be the process group leader]");
+    }
+
+    signal(SIGTERM, term_kill_soft);
+
+    while (getchar() != EOF) {
+       /* wait until EOF */
+    }
+
+    term_kill_soft(0);
+
+    for(;;) {
+       if (wait(&status) != -1)
+           break;
+       if (errno != EINTR) {
+           error("error [wait() failed: %s]", strerror(errno));
+           return -1;
+       }
+    }
+
+    dbprintf(("child process exited with status %d\n", WEXITSTATUS(status)));
+
+    return WEXITSTATUS(status);
+}
+
+static void term_kill_soft(sig)
+int sig;
+{
+    pid_t dumppid = getpid();
+    int killerr;
+
+    signal(SIGTERM, SIG_IGN);
+    signal(SIGALRM, term_kill_hard);
+    alarm(3);
+    /*
+     * First, try to kill the dump process nicely.  If it ignores us
+     * for three seconds, hit it harder.
+     */
+    dbprintf(("sending SIGTERM to process group %ld\n", (long) dumppid));
+    killerr = kill(-dumppid, SIGTERM);
+    if (killerr == -1) {
+       dbprintf(("kill failed: %s\n", strerror(errno)));
+    }
+}
+
+static void term_kill_hard(sig)
+int sig;
+{
+    pid_t dumppid = getpid();
+    int killerr;
+
+    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);
+    /* should never reach this point, but so what? */
+    if (killerr == -1) {
+       dbprintf(("kill failed: %s\n", strerror(errno)));
+       dbprintf(("waiting until child terminates\n"));
+    }
+}
diff --git a/client-src/patch-system.sh.in b/client-src/patch-system.sh.in
new file mode 100644 (file)
index 0000000..a2d7cfb
--- /dev/null
@@ -0,0 +1,144 @@
+#! /bin/sh
+#
+# patch inetd.conf and services
+# originally by Axel Zinser (fifi@hiss.han.de)
+#
+
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+libexecdir="@libexecdir@"
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+SERVICE_SUFFIX="@SERVICE_SUFFIX@"
+
+USER="@CLIENT_LOGIN@"
+
+INETDCONF=/etc/inetd.conf
+[ ! -f $INETDCONF ] && INETDCONF=/usr/etc/inetd.conf
+
+SERVICES=/etc/services
+[ ! -f $SERVICES ] && SERVICES=/usr/etc/services
+
+ENABLE_AMANDAD=true
+
+case `uname -n` in
+"@DEFAULT_SERVER@" | "@DEFAULT_SERVER@".*)
+    ENABLE_INDEX=true
+    ENABLE_TAPE=true
+    ;;
+*)
+    ENABLE_INDEX=false
+    ENABLE_TAPE=false
+    ;;
+esac
+
+CLIENT_PORT=10080
+KCLIENT_PORT=10081
+INDEX_PORT=10082
+TAPE_PORT=10083
+
+while [ $# != 0 ]; do
+    case "$1" in
+    --service-suffix=*)
+       SERVICE_SUFFIX=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --version-suffix=*)
+       SUF=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --inetd=*)
+        INETDCONF=`echo $1 | sed -e 's/[^=]*=//' -e 's%^$%/dev/null%'`;;
+    --services=*)
+       SERVICES=`echo $1 | sed -e 's/[^=]*=//' -e 's%^$%/dev/null%'`;;
+    --libexecdir=?*)
+       libexecdir=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --user=?*)
+       USER=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --enable-client)
+       ENABLE_AMANDAD=true;;
+    --disable-client)
+       ENABLE_AMANDAD=false;;
+    --enable-index)
+       ENABLE_INDEX=true;;
+    --disable-index)
+       ENABLE_INDEX=false;;
+    --enable-tape)
+       ENABLE_TAPE=true;;
+    --disable-tape)
+       ENABLE_TAPE=false;;
+    --client-port=?*)
+       CLIENT_PORT=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --kclient-port=?*)
+       KCLIENT_PORT=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --index-port=?*)
+       INDEX_PORT=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --tape-port=?*)
+       TAPE_PORT=`echo $1 | sed -e 's/[^=]*=//'`;;
+    --usage | --help | -h)
+       echo "call this script with zero or more of the following arguments:"
+       echo "--version-suffix=<suffix>: append to program names [$SUF]"
+       echo "--service-suffix=<suffix>: append to service names [$SERVICE_SUFFIX]"
+       echo "--libexecdir=<dirname>: where daemons should be looked for [$libexecdir]"
+       echo "--inetd=<pathname>: full pathname of inetd.conf [$INETDCONF]"
+       echo "--services=<pathname>: full pathname of services [$SERVICES]"
+       echo "    an empty pathname or /dev/null causes that file to be skipped"
+       echo "--user=<username>: run deamons as this user [$USER]"
+       echo "--enable/disable-client: enable/disable amandad [`$ENABLE_AMANDAD && echo enabled || echo disabled`]"
+       echo "--enable/disable-index: enable/disable index server [`$ENABLE_INDEX && echo enabled || echo disabled`]"
+       echo "--enable/disable-tape: enable/disable tape server [`$ENABLE_TAPE && echo enabled || echo disabled`]"
+       echo "--client-port=<num>: amandad port number [$CLIENT_PORT]"
+       echo "--kclient-port=<num>: kamandad port number [$KCLIENT_PORT]"
+       echo "--index-port=<num>: index server port number [$INDEX_PORT]"
+       echo "--tape-port=<num>: tape server port number [$TAPE_PORT]"
+       exec true;;
+    *)
+       echo "$0: invalid argument $1.  run with -h for usage" >&2
+       exec false;;
+    esac
+    shift
+done
+
+if [ "$SERVICES" = /dev/null ]; then :
+elif [ -f "$SERVICES" ]; then
+       TEMP="$SERVICES.new"
+       {
+           egrep < "$SERVICES" -v "^(amanda|kamanda|amandaidx|amidxtape)${SERVICE_SUFFIX}[     ]"
+           echo "amanda${SERVICE_SUFFIX} ${CLIENT_PORT}/udp"
+           echo "amanda${SERVICE_SUFFIX} ${CLIENT_PORT}/tcp"
+           echo "kamanda${SERVICE_SUFFIX} ${KCLIENT_PORT}/udp"
+           echo "amandaidx${SERVICE_SUFFIX} ${INDEX_PORT}/tcp"
+           echo "amidxtape${SERVICE_SUFFIX} ${TAPE_PORT}/tcp"
+       } > "$TEMP"
+       if diff "$SERVICES" "$TEMP" >/dev/null 2>/dev/null; then
+               echo "$SERVICES is up to date"
+       else
+               cp "$TEMP" "$SERVICES" || echo "cannot patch $SERVICES"
+       fi
+       rm -f "$TEMP"
+else
+       echo "$SERVICES not found!"
+fi
+if [ "$INETDCONF" = /dev/null ]; then :
+elif [ -f "$INETDCONF" ]; then
+       $ENABLE_AMANDAD && test ! -f $libexecdir/amandad$SUF && echo "warning: $libexecdir/amandad$SUF does not exist" >&2
+       $ENABLE_INDEX && test ! -f $libexecdir/amindexd$SUF && echo "warning: $libexecdir/amindexd$SUF does not exist" >&2
+       $ENABLE_TAPE && test ! -f $libexecdir/amidxtaped$SUF && echo "warning: $libexecdir/amidxtaped$SUF does not exist" >&2
+       TEMP="$INETDCONF.new"
+       {
+           egrep < "$INETDCONF" -v "^(amanda|amandaidx|amidxtape)${SERVICE_SUFFIX}[    ]"
+           $ENABLE_AMANDAD && echo "amanda${SERVICE_SUFFIX}    dgram  udp wait   $USER $libexecdir/amandad$SUF    amandad$SUF"
+           $ENABLE_INDEX && echo "amandaidx${SERVICE_SUFFIX} stream tcp nowait $USER $libexecdir/amindexd$SUF   amindexd$SUF"
+           $ENABLE_TAPE && echo "amidxtape${SERVICE_SUFFIX} stream tcp nowait $USER $libexecdir/amidxtaped$SUF amidxtaped$SUF"
+       } > "$TEMP"
+       if diff "$INETDCONF" "$TEMP" >/dev/null 2>/dev/null; then
+               echo "$INETDCONF is up to date"
+       else
+               cp "$TEMP" "$INETDCONF" || echo "cannot patch $INETDCONF"
+       fi
+       rm -f "$TEMP"
+else
+       echo "$INETDCONF not found!"
+fi
diff --git a/client-src/rundump.c b/client-src/rundump.c
new file mode 100644 (file)
index 0000000..26814e6
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * 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: rundump.c,v 1.23.2.3.6.1 2002/10/27 14:31:18 martinea Exp $
+ *
+ * runs DUMP program as root
+ */
+#include "amanda.h"
+#include "version.h"
+
+int main P((int argc, char **argv));
+
+#if defined(VDUMP) || defined(XFSDUMP)
+#  define USE_RUNDUMP
+#endif
+
+#if !defined(USE_RUNDUMP)
+#  define ERRMSG "rundump not enabled on this system.\n"
+#else
+#  if !defined(DUMP) && !defined(VXDUMP) && !defined(VDUMP) && !defined(XFSDUMP)
+#    define ERRMSG "DUMP not available on this system.\n"
+#  else
+#    undef ERRMSG
+#  endif
+#endif
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+#ifndef ERRMSG
+    char *dump_program;
+    int i;
+    char *e;
+#endif /* ERRMSG */
+    int fd;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("rundump");
+
+    dbopen();
+    dbprintf(("%s: version %s\n", argv[0], version()));
+
+#ifdef ERRMSG                                                  /* { */
+
+    fprintf(stderr, ERRMSG);
+    dbprintf(("%s: %s", argv[0], ERRMSG));
+    dbclose();
+    return 1;
+
+#else                                                          /* } { */
+
+    if(client_uid == (uid_t) -1) {
+       error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+    }
+
+#ifdef FORCE_USERID
+    if (getuid() != client_uid) {
+       error("error [must be invoked by %s]\n", CLIENT_LOGIN);
+    }
+
+    if (geteuid() != 0) {
+       error("error [must be setuid root]\n");
+    }
+#endif /* FORCE_USERID */
+
+#if !defined (DONT_SUID_ROOT)
+    setuid(0);
+#endif
+
+#ifdef XFSDUMP
+
+    if (strcmp(argv[0], "xfsdump") == 0)
+        dump_program = XFSDUMP;
+    else /* strcmp(argv[0], "xfsdump") != 0 */
+
+#endif
+
+#ifdef VXDUMP
+
+    if (strcmp(argv[0], "vxdump") == 0)
+        dump_program = VXDUMP;
+    else /* strcmp(argv[0], "vxdump") != 0 */
+
+#endif
+
+#ifdef VDUMP
+
+    if (strcmp(argv[0], "vdump") == 0)
+       dump_program = VDUMP;
+    else /* strcmp(argv[0], "vdump") != 0 */
+
+#endif
+
+#if defined(DUMP)
+        dump_program = DUMP;
+#else
+# if defined(XFSDUMP)
+        dump_program = XFSDUMP;
+# else
+#  if defined(VXDUMP)
+       dump_program = VXDUMP;
+#  else
+        dump_program = "dump";
+#  endif
+# endif
+#endif
+
+    dbprintf(("running: %s: ",dump_program));
+    for (i=0; argv[i]; i++)
+       dbprintf(("%s ", argv[i]));
+    dbprintf(("\n"));
+
+    execve(dump_program, argv, safe_env());
+
+    e = strerror(errno);
+    dbprintf(("execve of %s failed (%s)\n", dump_program, e));
+    dbclose();
+
+    fprintf(stderr, "rundump: could not exec %s: %s\n", dump_program, e);
+    return 1;
+#endif                                                         /* } */
+}
diff --git a/client-src/runtar.c b/client-src/runtar.c
new file mode 100644 (file)
index 0000000..c8e9e6b
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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: runtar.c,v 1.11.4.2.6.1 2002/10/27 14:31:18 martinea Exp $
+ *
+ * runs GNUTAR program as root
+ */
+#include "amanda.h"
+#include "version.h"
+
+int main P((int argc, char **argv));
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+#ifdef GNUTAR
+    int i;
+#endif
+    int fd;
+    char *e;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("runtar");
+
+    dbopen();
+    dbprintf(("%s: version %s\n", argv[0], version()));
+
+#ifndef GNUTAR
+
+    fprintf(stderr,"gnutar not available on this system.\n");
+    dbprintf(("%s: gnutar not available on this system.\n", argv[0]));
+    dbclose();
+    return 1;
+
+#else
+
+    if(client_uid == (uid_t) -1) {
+       error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+    }
+
+#ifdef FORCE_USERID
+    if (getuid() != client_uid) {
+       error("error [must be invoked by %s]\n", CLIENT_LOGIN);
+    }
+
+    if (geteuid() != 0) {
+       error("error [must be setuid root]\n");
+    }
+#endif
+
+#if !defined (DONT_SUID_ROOT)
+    setuid(0);
+#endif
+
+    dbprintf(("running: %s: ",GNUTAR));
+    for (i=0; argv[i]; i++)
+       dbprintf(("%s ", argv[i]));
+    dbprintf(("\n"));
+
+    execve(GNUTAR, argv, safe_env());
+
+    e = strerror(errno);
+    dbprintf(("execve of %s failed (%s)\n", GNUTAR, e));
+    dbclose();
+
+    fprintf(stderr, "runtar: could not exec %s: %s\n", GNUTAR, e);
+    return 1;
+#endif
+}
diff --git a/client-src/selfcheck.c b/client-src/selfcheck.c
new file mode 100644 (file)
index 0000000..0cfade8
--- /dev/null
@@ -0,0 +1,857 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/* 
+ * $Id: selfcheck.c,v 1.40.2.3.4.4.2.22 2003/11/18 18:04:26 martinea Exp $
+ *
+ * do self-check and send back any error messages
+ */
+
+#include "amanda.h"
+#include "clock.h"
+#include "statfs.h"
+#include "version.h"
+#include "getfsent.h"
+#include "amandates.h"
+#include "util.h"
+#include "pipespawn.h"
+#include "amfeatures.h"
+#include "client_util.h"
+
+#ifdef SAMBA_CLIENT
+#include "findpass.h"
+#endif
+
+int need_samba=0;
+int need_rundump=0;
+int need_dump=0;
+int need_restore=0;
+int need_vdump=0;
+int need_vrestore=0;
+int need_xfsdump=0;
+int need_xfsrestore=0;
+int need_vxdump=0;
+int need_vxrestore=0;
+int need_runtar=0;
+int need_gnutar=0;
+int need_compress_path=0;
+
+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 *disk, char *device, option_t *options));
+static void check_disk P((char *program, char *disk, char *amdevice, int level));
+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 level;
+    char *line = NULL;
+    char *program = NULL;
+    char *disk = NULL;
+    char *device = NULL;
+    char *optstr = NULL;
+    char *err_extra = NULL;
+    char *s, *fp;
+    int ch;
+    int fd;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    option_t *options;
+
+    /* initialize */
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("selfcheck");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
+    dbopen();
+    startclock();
+    dbprintf(("%s: version %s\n", argv[0], version()));
+
+    our_features = am_init_feature_set();
+    our_feature_string = am_feature_to_string(our_features);
+
+    /* handle all service requests */
+
+    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';
+           }
+
+           printf("OPTIONS ");
+           if(am_has_feature(g_options->features, fe_rep_options_features)) {
+               printf("features=%s;", our_feature_string);
+           }
+           if(am_has_feature(g_options->features, fe_rep_options_hostname)) {
+               printf("hostname=%s;", g_options->hostname);
+           }
+           printf("\n");
+           fflush(stdout);
+           continue;
+       }
+
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);                 /* find program name */
+       if (ch == '\0') {
+           goto err;                           /* no program */
+       }
+       program = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';                           /* terminate the program name */
+
+       skip_whitespace(s, ch);                 /* find disk name */
+       if (ch == '\0') {
+           goto err;                           /* no disk */
+       }
+       disk = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';                           /* terminate the disk name */
+
+       skip_whitespace(s, ch);                 /* find the device or level */
+       if (ch == '\0') {
+           goto err;                           /* no device or level */
+       }
+       if(!isdigit((int)s[-1])) {
+           fp = s - 1;
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';                       /* terminate the device */
+           device = stralloc(fp);
+           skip_whitespace(s, ch);             /* find level number */
+       }
+       else {
+           device = stralloc(disk);
+       }
+
+                                               /* find level number */
+       if (ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           goto err;                           /* bad level */
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+#define sc "OPTIONS "
+       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 */
+           if(ch == '\0') {
+               goto err;                       /* bad options string */
+           }
+           optstr = s - 1;
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';                       /* terminate the options */
+           options = parse_options(optstr, disk, device, g_options->features, 1);
+           check_options(program, disk, device, options);
+           check_disk(program, disk, device, level);
+           free_sl(options->exclude_file);
+           free_sl(options->exclude_list);
+           free_sl(options->include_file);
+           free_sl(options->include_list);
+           amfree(options->str);
+           amfree(options);
+       } else if (ch == '\0') {
+           /* check all since no option */
+           need_samba=1;
+           need_rundump=1;
+           need_dump=1;
+           need_restore=1;
+           need_vdump=1;
+           need_vrestore=1;
+           need_xfsdump=1;
+           need_xfsrestore=1;
+           need_vxdump=1;
+           need_vxrestore=1;
+           need_runtar=1;
+           need_gnutar=1;
+           need_compress_path=1;
+           check_disk(program, disk, device, level);
+       } else {
+           goto err;                           /* bad syntax */
+       }
+       amfree(device);
+    }
+
+    check_overall();
+
+    amfree(line);
+    amfree(our_feature_string);
+    am_release_feature_set(our_features);
+    our_features = NULL;
+    am_release_feature_set(g_options->features);
+    g_options->features = NULL;
+    amfree(g_options->str);
+    amfree(g_options->hostname);
+    amfree(g_options);
+
+    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
+    }
+
+    dbclose();
+    return 0;
+
+ err:
+    printf("ERROR [BOGUS REQUEST PACKET]\n");
+    dbprintf(("%s: REQ packet is bogus%s%s\n",
+             debug_prefix_time(NULL),
+             err_extra ? ": " : "",
+             err_extra ? err_extra : ""));
+    dbclose();
+    return 1;
+}
+
+
+static void
+check_options(program, disk, device, options)
+    char *program, *disk, *device;
+    option_t *options;
+{
+    if(strcmp(program,"GNUTAR") == 0) {
+       need_gnutar=1;
+        if(disk[0] == '/' && disk[1] == '/') {
+           if(options->exclude_file && options->exclude_file->nb_element > 1) {
+               printf("ERROR [samba support only one exclude file]\n");
+           }
+           if(options->exclude_list && options->exclude_list->nb_element > 0 &&
+              options->exclude_optional==0) {
+               printf("ERROR [samba does not support exclude list]\n");
+           }
+           if(options->include_file && options->include_file->nb_element > 0) {
+               printf("ERROR [samba does not support include file]\n");
+           }
+           if(options->include_list && options->include_list->nb_element > 0 &&
+              options->include_optional==0) {
+               printf("ERROR [samba does not support include list]\n");
+           }
+           need_samba=1;
+       }
+       else {
+           int nb_exclude = 0;
+           int nb_include = 0;
+           char *file_exclude = NULL;
+           char *file_include = NULL;
+
+           if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
+           if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
+           if(options->include_file) nb_include += options->include_file->nb_element;
+           if(options->include_list) nb_include += options->include_list->nb_element;
+
+           if(nb_exclude > 0) file_exclude = build_exclude(disk, device, options, 1);
+           if(nb_include > 0) file_include = build_include(disk, device, options, 1);
+
+           amfree(file_exclude);
+           amfree(file_include);
+
+           need_runtar=1;
+       }
+    }
+    if(strcmp(program,"DUMP") == 0) {
+       if(options->exclude_file && options->exclude_file->nb_element > 0) {
+           printf("ERROR [DUMP does not support exclude file]\n");
+       }
+       if(options->exclude_list && options->exclude_list->nb_element > 0) {
+           printf("ERROR [DUMP does not support exclude list]\n");
+       }
+       if(options->include_file && options->include_file->nb_element > 0) {
+           printf("ERROR [DUMP does not support include file]\n");
+       }
+       if(options->include_list && options->include_list->nb_element > 0) {
+           printf("ERROR [DUMP does not support include list]\n");
+       }
+#ifdef USE_RUNDUMP
+       need_rundump=1;
+#endif
+#ifndef AIX_BACKUP
+#ifdef VDUMP
+#ifdef DUMP
+       if (strcmp(amname_to_fstype(disk), "advfs") == 0)
+#else
+       if (1)
+#endif
+       {
+           need_vdump=1;
+           need_rundump=1;
+           if (options->createindex)
+               need_vrestore=1;
+       }
+       else
+#endif /* VDUMP */
+#ifdef XFSDUMP
+#ifdef DUMP
+       if (strcmp(amname_to_fstype(disk), "xfs") == 0)
+#else
+       if (1)
+#endif
+       {
+           need_xfsdump=1;
+           need_rundump=1;
+           if (options->createindex)
+               need_xfsrestore=1;
+       }
+       else
+#endif /* XFSDUMP */
+#ifdef VXDUMP
+#ifdef DUMP
+       if (strcmp(amname_to_fstype(disk), "vxfs") == 0)
+#else
+       if (1)
+#endif
+       {
+           need_vxdump=1;
+           if (options->createindex)
+               need_vxrestore=1;
+       }
+       else
+#endif /* VXDUMP */
+       {
+           need_dump=1;
+           if (options->createindex)
+               need_restore=1;
+       }
+#else
+       /* AIX backup program */
+       need_dump=1;
+       if (options->createindex)
+           need_restore=1;
+#endif
+    }
+    if(options->compress == COMPR_BEST || options->compress == COMPR_FAST) 
+       need_compress_path=1;
+}
+
+static void check_disk(program, disk, amdevice, level)
+char *program, *disk, *amdevice;
+int level;
+{
+    char *device = NULL;
+    char *err = NULL;
+    char *user_and_password = NULL, *domain = NULL;
+    char *share = NULL, *subdir = NULL;
+    int lpass = 0;
+    int amode;
+    int access_result;
+    char *access_type;
+    char *extra_info = NULL;
+
+    dbprintf(("%s: checking disk %s\n", debug_prefix_time(NULL), disk));
+
+    if (strcmp(program, "GNUTAR") == 0) {
+        if(amdevice[0] == '/' && amdevice[1] == '/') {
+#ifdef SAMBA_CLIENT
+           int nullfd, checkerr;
+           int passwdfd;
+           char *pwtext;
+           int pwtext_len;
+           int checkpid;
+           amwait_t retstat;
+           char number[NUM_STR_SIZE];
+           int wpid;
+           int ret, sig, rc;
+           char *line;
+           char *sep;
+           FILE *ferr;
+           char *pw_fd_env;
+           int errdos;
+
+           parsesharename(amdevice, &share, &subdir);
+           if (!share) {
+               err = stralloc2("cannot parse for share/subdir disk entry ", amdevice);
+               goto common_exit;
+           }
+           if ((subdir) && (SAMBA_VERSION < 2)) {
+               err = vstralloc("subdirectory specified for share '",
+                               amdevice,
+                               "' but samba not v2 or better",
+                               NULL);
+               goto common_exit;
+           }
+           if ((user_and_password = findpass(share, &domain)) == NULL) {
+               err = stralloc2("cannot find password for ", amdevice);
+               goto common_exit;
+           }
+           lpass = strlen(user_and_password);
+           if ((pwtext = strchr(user_and_password, '%')) == NULL) {
+               err = stralloc2("password field not \'user%pass\' for ", amdevice);
+               goto common_exit;
+           }
+           *pwtext++ = '\0';
+           pwtext_len = strlen(pwtext);
+           if ((device = makesharename(share, 0)) == NULL) {
+               err = stralloc2("cannot make share name of ", share);
+               goto common_exit;
+           }
+
+           nullfd = open("/dev/null", O_RDWR);
+           if (pwtext_len > 0) {
+               pw_fd_env = "PASSWD_FD";
+           } else {
+               pw_fd_env = "dummy_PASSWD_FD";
+           }
+           checkpid = pipespawn(SAMBA_CLIENT, STDERR_PIPE|PASSWD_PIPE,
+                                &nullfd, &nullfd, &checkerr,
+                                pw_fd_env, &passwdfd,
+                                "smbclient",
+                                device,
+                                *user_and_password ? "-U" : skip_argument,
+                                *user_and_password ? user_and_password : skip_argument,
+                                "-E",
+                                domain ? "-W" : skip_argument,
+                                domain ? domain : skip_argument,
+#if SAMBA_VERSION >= 2
+                                subdir ? "-D" : skip_argument,
+                                subdir ? subdir : skip_argument,
+#endif
+                                "-c", "quit",
+                                NULL);
+           if (domain) {
+               memset(domain, '\0', strlen(domain));
+               amfree(domain);
+           }
+           aclose(nullfd);
+           if (pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) {
+               err = vstralloc("password write failed: ",
+                               amdevice,
+                               ": ",
+                               strerror(errno),
+                               NULL);
+               aclose(passwdfd);
+               goto common_exit;
+           }
+           memset(user_and_password, '\0', lpass);
+           amfree(user_and_password);
+           aclose(passwdfd);
+           ferr = fdopen(checkerr, "r");
+           sep = "";
+           errdos = 0;
+           for(sep = ""; (line = agets(ferr)) != NULL; free(line)) {
+               strappend(extra_info, sep);
+               strappend(extra_info, line);
+               sep = ": ";
+               if(strstr(line, "ERRDOS") != NULL) {
+                   errdos = 1;
+               }
+           }
+           afclose(ferr);
+           checkerr = -1;
+           rc = 0;
+           while ((wpid = wait(&retstat)) != -1) {
+               if (WIFSIGNALED(retstat)) {
+                   ret = 0;
+                   rc = sig = WTERMSIG(retstat);
+               } else {
+                   sig = 0;
+                   rc = ret = WEXITSTATUS(retstat);
+               }
+               if (rc != 0) {
+                   strappend(err, sep);
+                   if (ret == 0) {
+                       strappend(err, "got signal ");
+                       ret = sig;
+                   } else {
+                       strappend(err, "returned ");
+                   }
+                   ap_snprintf(number, sizeof(number), "%d", ret);
+                   strappend(err, number);
+               }
+           }
+           if (errdos != 0 || rc != 0) {
+               err = newvstralloc(err,
+                                  "samba access error: ",
+                                  amdevice,
+                                  ": ",
+                                  extra_info ? extra_info : "",
+                                  err,
+                                  NULL);
+               amfree(extra_info);
+           }
+#else
+           err = stralloc2("This client is not configured for samba: ", amdevice);
+#endif
+           goto common_exit;
+       }
+       amode = F_OK;
+       device = amname_to_dirname(amdevice);
+    } else {
+       if(amdevice[0] == '/' && amdevice[1] == '/') {
+           err = vstralloc("The DUMP program cannot handle samba shares,",
+                           " use GNUTAR: ",
+                           amdevice,
+                           NULL);
+           goto common_exit;
+       }
+#ifdef VDUMP                                                           /* { */
+#ifdef DUMP                                                            /* { */
+        if (strcmp(amname_to_fstype(amdevice), "advfs") == 0)
+#else                                                                  /* }{ */
+       if (1)
+#endif                                                                 /* } */
+       {
+           device = amname_to_dirname(amdevice);
+           amode = F_OK;
+       } else
+#endif                                                                 /* } */
+       {
+           device = amname_to_devname(amdevice);
+#ifdef USE_RUNDUMP
+           amode = F_OK;
+#else
+           amode = R_OK;
+#endif
+       }
+    }
+
+    dbprintf(("%s: device %s\n", debug_prefix_time(NULL), device));
+
+    /* skip accessability test if this is an AFS entry */
+    if(strncmp(device, "afs:", 4) != 0) {
+#ifdef CHECK_FOR_ACCESS_WITH_OPEN
+       access_result = open(device, O_RDONLY);
+       access_type = "open";
+#else
+       access_result = access(device, amode);
+       access_type = "access";
+#endif
+       if(access_result == -1) {
+           err = vstralloc("could not ", access_type, " ", device,
+                       " (", disk, "): ", strerror(errno), NULL);
+       }
+#ifdef CHECK_FOR_ACCESS_WITH_OPEN
+       aclose(access_result);
+#endif
+    }
+
+common_exit:
+
+    amfree(share);
+    amfree(subdir);
+    if(user_and_password) {
+       memset(user_and_password, '\0', lpass);
+       amfree(user_and_password);
+    }
+    if(domain) {
+       memset(domain, '\0', strlen(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));
+    }
+    if(extra_info) {
+       dbprintf(("%s: extra info: %s\n", debug_prefix_time(NULL), extra_info));
+       amfree(extra_info);
+    }
+    amfree(device);
+
+    /* XXX perhaps do something with level: read dumpdates and sanity check */
+}
+
+static void check_overall()
+{
+    char *cmd;
+    struct stat buf;
+    int testfd;
+
+    if( need_runtar )
+    {
+       cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
+       check_file(cmd,X_OK);
+       check_suid(cmd);
+       amfree(cmd);
+    }
+
+    if( need_rundump )
+    {
+       cmd = vstralloc(libexecdir, "/", "rundump", versionsuffix(), NULL);
+       check_file(cmd,X_OK);
+       check_suid(cmd);
+       amfree(cmd);
+    }
+
+    if( need_dump ) {
+#ifdef DUMP
+       check_file(DUMP, X_OK);
+#else
+       printf("ERROR [DUMP program not available]\n");
+#endif
+    }
+
+    if( need_restore ) {
+#ifdef RESTORE
+       check_file(RESTORE, X_OK);
+#else
+       printf("ERROR [RESTORE program not available]\n");
+#endif
+    }
+
+    if ( need_vdump ) {
+#ifdef VDUMP
+       check_file(VDUMP, X_OK);
+#else
+       printf("ERROR [VDUMP program not available]\n");
+#endif
+    }
+
+    if ( need_vrestore ) {
+#ifdef VRESTORE
+       check_file(VRESTORE, X_OK);
+#else
+       printf("ERROR [VRESTORE program not available]\n");
+#endif
+    }
+
+    if( need_xfsdump ) {
+#ifdef XFSDUMP
+       check_file(XFSDUMP, F_OK);
+#else
+       printf("ERROR [XFSDUMP program not available]\n");
+#endif
+    }
+
+    if( need_xfsrestore ) {
+#ifdef XFSRESTORE
+       check_file(XFSRESTORE, X_OK);
+#else
+       printf("ERROR [XFSRESTORE program not available]\n");
+#endif
+    }
+
+    if( need_vxdump ) {
+#ifdef VXDUMP
+       check_file(VXDUMP, X_OK);
+#else
+       printf("ERROR [VXDUMP program not available]\n");
+#endif
+    }
+
+    if( need_vxrestore ) {
+#ifdef VXRESTORE
+       check_file(VXRESTORE, X_OK);
+#else
+       printf("ERROR [VXRESTORE program not available]\n");
+#endif
+    }
+
+    if( need_gnutar ) {
+#ifdef GNUTAR
+       check_file(GNUTAR, X_OK);
+#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
+    }
+
+    if( need_samba ) {
+#ifdef SAMBA_CLIENT
+       check_file(SAMBA_CLIENT, X_OK);
+#else
+       printf("ERROR [SMBCLIENT program not available]\n");
+#endif
+       testfd = open("/etc/amandapass", R_OK);
+       if (testfd >= 0) {
+           if(fstat(testfd, &buf) == 0) {
+               if ((buf.st_mode & 0x7) != 0) {
+                   printf("ERROR [/etc/amandapass is world readable!]\n");
+               } else {
+                   printf("OK [/etc/amandapass is readable, but not by all]\n");
+               }
+           } else {
+               printf("OK [unable to stat /etc/amandapass: %s]\n",
+                      strerror(errno));
+           }
+           aclose(testfd);
+       } else {
+           printf("ERROR [unable to open /etc/amandapass: %s]\n",
+                  strerror(errno));
+       }
+    }
+
+    if( need_compress_path ) {
+       check_file(COMPRESS_PATH, X_OK);
+    }
+
+    if( need_dump || need_xfsdump )
+       check_file("/etc/dumpdates",
+#ifdef USE_RUNDUMP
+                  F_OK
+#else
+                  R_OK|W_OK
+#endif
+                  );
+
+    if (need_vdump) {
+        check_file("/etc/vdumpdates", F_OK);
+    }
+
+    check_access("/dev/null", R_OK|W_OK);
+    check_space(AMANDA_TMPDIR, 64);    /* for amandad i/o */
+
+#ifdef AMANDA_DBGDIR
+    check_space(AMANDA_DBGDIR, 64);    /* for amandad i/o */
+#endif
+
+    check_space("/etc", 64);           /* for /etc/dumpdates writing */
+}
+
+static void check_space(dir, kbytes)
+char *dir;
+long 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);
+}
+
+static void check_access(filename, mode)
+char *filename;
+int mode;
+{
+    char *noun, *adjective;
+
+    if(mode == F_OK)
+        noun = "find", adjective = "exists";
+    else if((mode & X_OK) == X_OK)
+       noun = "execute", adjective = "executable";
+    else if((mode & (W_OK|R_OK)) == (W_OK|R_OK))
+       noun = "read/write", adjective = "read/writable";
+    else 
+       noun = "access", adjective = "accessible";
+
+    if(access(filename, mode) == -1)
+       printf("ERROR [can not %s %s: %s]\n", noun, filename, strerror(errno));
+    else
+       printf("OK %s %s\n", filename, adjective);
+}
+
+static void check_file(filename, mode)
+char *filename;
+int mode;
+{
+    struct stat stat_buf;
+    if(!stat(filename, &stat_buf)) {
+       if(!S_ISREG(stat_buf.st_mode)) {
+           printf("ERROR [%s is not a file]\n", filename);
+       }
+    }
+    check_access(filename, mode);
+}
+
+static void check_dir(dirname, mode)
+char *dirname;
+int mode;
+{
+    struct stat stat_buf;
+    char *dir;
+
+    if(!stat(dirname, &stat_buf)) {
+       if(!S_ISDIR(stat_buf.st_mode)) {
+           printf("ERROR [%s is not a directory]\n", dirname);
+       }
+    }
+    dir = stralloc2(dirname, "/.");
+    check_access(dir, mode);
+    amfree(dir);
+}
+
+static void check_suid(filename)
+char *filename;
+{
+/* The following is only valid for real Unixs */
+#ifndef IGNORE_UID_CHECK
+    struct stat stat_buf;
+    if(!stat(filename, &stat_buf)) {
+       if(stat_buf.st_uid != 0 ) {
+           printf("ERROR [%s is not owned by root]\n",filename);
+       }
+       if((stat_buf.st_mode & S_ISUID) != S_ISUID) {
+           printf("ERROR [%s is not SUID root]\n",filename);
+       }
+    }
+    else {
+       printf("ERROR [can not stat %s]\n",filename);
+    }
+#endif
+}
diff --git a/client-src/sendbackup-dump.c b/client-src/sendbackup-dump.c
new file mode 100644 (file)
index 0000000..f0a3af5
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * 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: sendbackup-dump.c,v 1.65.2.5.4.2.2.9 2003/02/05 02:11:26 martinea Exp $
+ *
+ * send backup data using BSD dump
+ */
+
+#include "sendbackup.h"
+#include "clock.h"
+#include "getfsent.h"
+#include "version.h"
+
+#ifdef KRB4_SECURITY
+#include "sendbackup-krb4.h"
+#else                                  /* I'd tell you what this does */
+#define NAUGHTY_BITS                   /* but then I'd have to kill you */
+#endif
+
+#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[] = {
+  /* the various encodings of dump size */
+  /* this should also match BSDI pre-3.0's buggy dump program, that
+     produced doubled DUMP: DUMP: messages */
+  AM_SIZE_RE("DUMP: [0-9][0-9]* tape blocks", 1024),
+  AM_SIZE_RE("dump: Actual: [0-9][0-9]* tape blocks", 1024),
+  AM_SIZE_RE("backup: There are [0-9][0-9]* tape blocks on [0-9][0-9]* tapes",
+            1024),
+  AM_SIZE_RE("backup: [0-9][0-9]* tape blocks on [0-9][0-9]* tape\\(s\\)",
+            1024),
+  AM_SIZE_RE("backup: [0-9][0-9]* 1k blocks on [0-9][0-9]* volume\\(s\\)",
+            1024),
+  AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*KB\\) on [0-9][0-9]* volume",
+            512),
+
+  AM_SIZE_RE("DUMP: [0-9][0-9]* blocks \\([0-9][0-9]*\\.[0-9][0-9]*MB\\) on [0-9][0-9]* volume",
+            512),
+  AM_SIZE_RE("DUMP: [0-9][0-9]* blocks", 512),
+  AM_SIZE_RE("DUMP: [0-9][0-9]* bytes were dumped", 1),
+  /* OSF's vdump */
+  AM_SIZE_RE("vdump: Dumped  [0-9][0-9]* of [0-9][0-9]* bytes", 1),
+  /* DU 4.0a dump */
+  AM_SIZE_RE("dump: Actual: [0-9][0-9]* blocks output to pipe", 1024),
+  /* DU 4.0 vdump */
+  AM_SIZE_RE("dump: Dumped  [0-9][0-9]* of [0-9][0-9]* bytes", 1),
+  /* HPUX dump */
+  AM_SIZE_RE("DUMP: [0-9][0-9]* KB actual output", 1024),
+  /* HPUX 10.20 and above vxdump */
+  AM_SIZE_RE("vxdump: [0-9][0-9]* tape blocks", 1024),
+  /* UnixWare vxdump */
+  AM_SIZE_RE("vxdump: [0-9][0-9]* blocks", 1024),
+  /* SINIX vxdump */
+  AM_SIZE_RE("   VXDUMP: [0-9][0-9]* blocks", 512),
+  /* SINIX ufsdump */
+  AM_SIZE_RE("   UFSDUMP: [0-9][0-9]* blocks", 512),
+  /* Irix 6.2 xfs dump */
+  AM_SIZE_RE("xfsdump: media file size [0-9][0-9]* bytes", 1),
+  /* NetApp dump */
+  AM_SIZE_RE("DUMP: [0-9][0-9]* KB", 1024),
+
+  /* strange dump lines */
+  AM_STRANGE_RE("should not happen"),
+  AM_STRANGE_RE("Cannot open"),
+  AM_STRANGE_RE("[Ee]rror"),
+  AM_STRANGE_RE("[Ff]ail"),
+  /* XXX add more ERROR entries here by scanning dump sources? */
+
+  /* any blank or non-strange DUMP: lines are marked as normal */
+  AM_NORMAL_RE("^ *DUMP:"),
+  AM_NORMAL_RE("^dump:"),                              /* OSF/1 */
+  AM_NORMAL_RE("^vdump:"),                             /* OSF/1 */
+  AM_NORMAL_RE("^ *vxdump:"),                          /* HPUX10 */
+  AM_NORMAL_RE("^ *vxfs *vxdump:"),                    /* Solaris */
+  AM_NORMAL_RE("^xfsdump:"),                           /* IRIX xfs */
+  AM_NORMAL_RE("^ *VXDUMP:"),                          /* Sinix */
+  AM_NORMAL_RE("^ *UFSDUMP:"),                         /* Sinix */
+
+#ifdef VDUMP   /* this is for OSF/1 3.2's vdump for advfs */
+  AM_NORMAL_RE("^The -s option is ignored"),           /* OSF/1 */
+  AM_NORMAL_RE("^path"),                               /* OSF/1 */
+  AM_NORMAL_RE("^dev/fset"),                           /* OSF/1 */
+  AM_NORMAL_RE("^type"),                               /* OSF/1 */
+  AM_NORMAL_RE("^advfs id"),                           /* OSF/1 */
+  AM_NORMAL_RE("^[A-Z][a-z][a-z] [A-Z][a-z][a-z] .[0-9] [0-9]"), /* OSF/1 */
+#endif
+
+  AM_NORMAL_RE("^backup:"),                            /* AIX */
+  AM_NORMAL_RE("^        Use the umount command to unmount the filesystem"),
+
+  AM_NORMAL_RE("^[ \t]*$"),
+
+  /* catch-all; DMP_STRANGE is returned for all other lines */
+  AM_STRANGE_RE(NULL)
+};
+
+static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
+    char *host;
+    char *disk, *amdevice;
+    int level, dataf, mesgf, indexf;
+    char *dumpdate;
+{
+    int dumpin, dumpout;
+    char *dumpkeys = NULL;
+    char *device = NULL;
+    char *fstype = NULL;
+    char *cmd = NULL;
+    char *indexcmd = NULL;
+    char level_str[NUM_STR_SIZE];
+
+    ap_snprintf(level_str, sizeof(level_str), "%d", level);
+
+    fprintf(stderr, "%s: start [%s:%s level %d]\n",
+           get_pname(), host, disk, level);
+
+    NAUGHTY_BITS;
+
+    if(options->compress == COMPR_FAST || options->compress == COMPR_BEST) {
+       char *compopt = skip_argument;
+
+#if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
+       if(options->compress == COMPR_BEST) {
+           compopt = COMPRESS_BEST_OPT;
+       } else {
+           compopt = COMPRESS_FAST_OPT;
+       }
+#endif
+       comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE,
+                           &dumpout, &dataf, &mesgf,
+                           COMPRESS_PATH, compopt, NULL);
+       dbprintf(("%s: pid %ld: %s",
+                 debug_prefix_time("-dump"), (long)comppid, COMPRESS_PATH));
+       if(compopt != skip_argument) {
+           dbprintf((" %s", compopt));
+       }
+       dbprintf(("\n"));
+    } else {
+       dumpout = dataf;
+       comppid = -1;
+    }
+
+    /* invoke dump */
+    device = amname_to_devname(amdevice);
+    fstype = amname_to_fstype(amdevice);
+
+    dbprintf(("%s: dumping device '%s' with '%s'\n",
+             debug_prefix_time(NULL), device, fstype));
+
+#if defined(USE_RUNDUMP) || !defined(DUMP)
+    cmd = vstralloc(libexecdir, "/", "rundump", versionsuffix(), NULL);
+#else
+    cmd = stralloc(DUMP);
+#endif
+
+#ifndef AIX_BACKUP                                     /* { */
+    /* normal dump */
+#ifdef XFSDUMP                                         /* { */
+#ifdef DUMP                                            /* { */
+    if (strcmp(amname_to_fstype(amdevice), "xfs") == 0)
+#else                                                  /* } { */
+    if (1)
+#endif                                                 /* } */
+    {
+        char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
+                                           versionsuffix(), NULL);
+       program->backup_name  = XFSDUMP;
+       program->restore_name = XFSRESTORE;
+
+       indexcmd = vstralloc(XFSRESTORE,
+                            " -t",
+                            " -v", " silent",
+                            " -",
+                            " 2>/dev/null",
+                            " | sed",
+                            " -e", " \'s/^/\\//\'",
+                            NULL);
+       write_tapeheader();
+
+       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+
+       dumpkeys = stralloc(level_str);
+       dumppid = pipespawn(progname, STDIN_PIPE,
+                           &dumpin, &dumpout, &mesgf,
+                           "xfsdump",
+                           options->no_record ? "-J" : skip_argument,
+                           "-F",
+                           "-l", dumpkeys,
+                           "-",
+                           device,
+                           NULL);
+    }
+    else
+#endif                                                 /* } */
+#ifdef VXDUMP                                          /* { */
+#ifdef DUMP
+    if (strcmp(amname_to_fstype(amdevice), "vxfs") == 0)
+#else
+    if (1)
+#endif
+    {
+#ifdef USE_RUNDUMP
+        char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
+                                           versionsuffix(), NULL);
+#else
+       char *progname = cmd = newvstralloc(cmd, VXDUMP, NULL);
+#endif
+       program->backup_name  = VXDUMP;
+       program->restore_name = VXRESTORE;
+
+       dumpkeys = vstralloc(level_str,
+                            options->no_record ? "" : "u",
+                            "s",
+                            "f",
+                            NULL);
+
+       indexcmd = vstralloc(VXRESTORE,
+                            " -tvf", " -",
+                            " 2>/dev/null",
+                            " | ",
+                            LEAF_AND_DIRS,
+                            NULL);
+       write_tapeheader();
+
+       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+
+       dumppid = pipespawn(progname, STDIN_PIPE,
+                           &dumpin, &dumpout, &mesgf, 
+                           "vxdump",
+                           dumpkeys,
+                           "1048576",
+                           "-",
+                           device,
+                           NULL);
+    }
+    else
+#endif                                                 /* } */
+
+#ifdef VDUMP                                           /* { */
+#ifdef DUMP
+    if (strcmp(amname_to_fstype(amdevice), "advfs") == 0)
+#else
+    if (1)
+#endif
+    {
+        char *progname = cmd = newvstralloc(cmd, libexecdir, "/", "rundump",
+                                           versionsuffix(), NULL);
+       device = newstralloc(device, amname_to_dirname(amdevice));
+       program->backup_name  = VDUMP;
+       program->restore_name = VRESTORE;
+
+       dumpkeys = vstralloc(level_str,
+                            options->no_record ? "" : "u",
+                            "b",
+                            "f",
+                            NULL);
+
+       indexcmd = vstralloc(VRESTORE,
+                            " -tvf", " -",
+                            " 2>/dev/null",
+                            " | ",
+                            "sed -e \'\n/^\\./ {\ns/^\\.//\ns/, [0-9]*$//\ns/^\\.//\ns/ @-> .*$//\nt\n}\nd\n\'",
+                            NULL);
+       write_tapeheader();
+
+       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+
+       dumppid = pipespawn(cmd, STDIN_PIPE,
+                           &dumpin, &dumpout, &mesgf, 
+                           "vdump",
+                           dumpkeys,
+                           "60",
+                           "-",
+                           device,
+                           NULL);
+    }
+    else
+#endif                                                 /* } */
+
+    {
+#ifndef RESTORE
+#define RESTORE "restore"
+#endif
+
+       dumpkeys = vstralloc(level_str,
+                            options->no_record ? "" : "u",
+                            "s",
+#ifdef HAVE_HONOR_NODUMP
+                            "h",
+#endif
+                            "f",
+                            NULL);
+
+       indexcmd = vstralloc(RESTORE,
+                            " -tvf", " -",
+                            " 2>&1",
+                            /* not to /dev/null because of DU's dump */
+                            " | ",
+                            LEAF_AND_DIRS,
+                            NULL);
+       write_tapeheader();
+
+       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+
+       dumppid = pipespawn(cmd, STDIN_PIPE,
+                           &dumpin, &dumpout, &mesgf, 
+                           "dump",
+                           dumpkeys,
+                           "1048576",
+#ifdef HAVE_HONOR_NODUMP
+                           "0",
+#endif
+                           "-",
+                           device,
+                           NULL);
+    }
+#else                                                  /* } { */
+    /* AIX backup program */
+    dumpkeys = vstralloc("-",
+                        level_str,
+                        options->no_record ? "" : "u",
+                        "f",
+                        NULL);
+
+    indexcmd = vstralloc(RESTORE,
+                        " -B",
+                        " -tvf", " -",
+                        " 2>/dev/null",
+                        " | ",
+                        LEAF_AND_DIRS,
+                        NULL);
+    write_tapeheader();
+
+    start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+
+    dumppid = pipespawn(cmd, STDIN_PIPE,
+                       &dumpin, &dumpout, &mesgf, 
+                       "backup",
+                       dumpkeys,
+                       "-",
+                       device,
+                       NULL);
+#endif                                                 /* } */
+
+    amfree(dumpkeys);
+    amfree(device);
+    amfree(cmd);
+    amfree(indexcmd);
+
+    /* close the write ends of the pipes */
+
+    aclose(dumpin);
+    aclose(dumpout);
+    aclose(dataf);
+    aclose(mesgf);
+    if (options->createindex)
+       aclose(indexf);
+}
+
+static void end_backup(status)
+int status;
+{
+    /* don't need to do anything for dump */
+}
+
+backup_program_t dump_program = {
+  "DUMP",
+#ifdef DUMP
+  DUMP
+#else
+  "dump"
+#endif
+  ,
+  RESTORE
+  ,
+  re_table, start_backup, end_backup
+};
diff --git a/client-src/sendbackup-gnutar.c b/client-src/sendbackup-gnutar.c
new file mode 100644 (file)
index 0000000..2fdac32
--- /dev/null
@@ -0,0 +1,585 @@
+/*
+ * 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: sendbackup-gnutar.c,v 1.56.2.15.4.4.2.11 2003/10/30 18:04:45 martinea Exp $
+ *
+ * send backup data using GNU tar
+ */
+
+#include "amanda.h"
+#include "sendbackup.h"
+#include "amandates.h"
+#include "clock.h"
+#include "util.h"
+#include "getfsent.h"                  /* for amname_to_dirname lookup */
+#include "version.h"
+
+#ifdef SAMBA_CLIENT
+#include "findpass.h"
+#endif
+
+#ifdef KRB4_SECURITY
+#include "sendbackup-krb4.h"
+#else                                  /* I'd tell you what this does */
+#define NAUGHTY_BITS                   /* but then I'd have to kill you */
+#endif
+
+
+static regex_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:"),
+  AM_NORMAL_RE("^Throughput"),
+
+  /* GNU tar 1.13.17 will print this warning when (not) backing up a
+     Unix named socket.  */
+  AM_NORMAL_RE(": socket ignored$"),
+
+  /* GNUTAR produces a few error messages when files are modified or
+     removed while it is running.  They may cause data to be lost, but
+     then they may not.  We shouldn't consider them NORMAL until
+     further investigation.  */
+#ifdef IGNORE_TAR_ERRORS
+  AM_NORMAL_RE(": File .* shrunk by [0-9][0-9]* bytes, padding with zeros"),
+  AM_NORMAL_RE(": Cannot add file .*: No such file or directory$"),
+  AM_NORMAL_RE(": Error exit delayed from previous errors"),
+#endif
+  
+  /* samba may produce these output messages */
+  AM_NORMAL_RE("^[Aa]dded interface"),
+  AM_NORMAL_RE("^session request to "),
+  AM_NORMAL_RE("^tar: dumped [0-9][0-9]* (tar )?files"),
+
+#if SAMBA_VERSION < 2
+  AM_NORMAL_RE("^doing parameter"),
+  AM_NORMAL_RE("^pm_process\\(\\)"),
+  AM_NORMAL_RE("^adding IPC"),
+  AM_NORMAL_RE("^Opening"),
+  AM_NORMAL_RE("^Connect"),
+  AM_NORMAL_RE("^Domain="),
+  AM_NORMAL_RE("^max"),
+  AM_NORMAL_RE("^security="),
+  AM_NORMAL_RE("^capabilities"),
+  AM_NORMAL_RE("^Sec mode "),
+  AM_NORMAL_RE("^Got "),
+  AM_NORMAL_RE("^Chose protocol "),
+  AM_NORMAL_RE("^Server "),
+  AM_NORMAL_RE("^Timezone "),
+  AM_NORMAL_RE("^received"),
+  AM_NORMAL_RE("^FINDFIRST"),
+  AM_NORMAL_RE("^FINDNEXT"),
+  AM_NORMAL_RE("^dos_clean_name"),
+  AM_NORMAL_RE("^file"),
+  AM_NORMAL_RE("^getting file"),
+  AM_NORMAL_RE("^Rejected chained"),
+  AM_NORMAL_RE("^nread="),
+  AM_NORMAL_RE("^\\([0-9][0-9]* kb/s\\)"),
+  AM_NORMAL_RE("^\\([0-9][0-9]*\\.[0-9][0-9]* kb/s\\)"),
+  AM_NORMAL_RE("^[ \t]*[0-9][0-9]* \\([ \t]*[0-9][0-9]*\\.[0-9][0-9]* kb/s\\)"),
+  AM_NORMAL_RE("^[ \t]*directory "),
+  AM_NORMAL_RE("^load_client_codepage"),
+#endif
+
+#ifdef IGNORE_SMBCLIENT_ERRORS
+  /* This will cause amanda to ignore real errors, but that may be
+   * unavoidable when you're backing up system disks.  It seems to be
+   * a safe thing to do if you know what you're doing.  */
+  AM_NORMAL_RE("^ERRDOS - ERRbadshare opening remote file"),
+  AM_NORMAL_RE("^ERRDOS - ERRbadfile opening remote file"),
+  AM_NORMAL_RE("^ERRDOS - ERRnoaccess opening remote file"),
+  AM_NORMAL_RE("^ERRSRV - ERRaccess setting attributes on file"),
+  AM_NORMAL_RE("^ERRDOS - ERRnoaccess setting attributes on file"),
+#endif
+
+#if SAMBA_VERSION >= 2
+  /* Backup attempt of nonexisting directory */
+  AM_ERROR_RE("ERRDOS - ERRbadpath (Directory invalid.)"),
+#endif
+
+  /* catch-all: DMP_STRANGE is returned for all other lines */
+  AM_STRANGE_RE(NULL)
+};
+
+int cur_level;
+char *cur_disk;
+time_t cur_dumptime;
+
+#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+static char *incrname = NULL;
+#endif
+
+static void start_backup(host, disk, amdevice, level, dumpdate, dataf, mesgf, indexf)
+    char *host;
+    char *disk, *amdevice;
+    int level, dataf, mesgf, indexf;
+    char *dumpdate;
+{
+    int dumpin, dumpout;
+    char *cmd = NULL;
+    char *indexcmd = NULL;
+    char *dirname = NULL;
+    int l;
+    char dumptimestr[80];
+    struct tm *gmtm;
+    amandates_t *amdates;
+    time_t prev_dumptime;
+    char *error_pn = NULL;
+
+    error_pn = stralloc2(get_pname(), "-smbclient");
+
+    fprintf(stderr, "%s: start [%s:%s level %d]\n",
+           get_pname(), host, disk, level);
+
+    NAUGHTY_BITS;
+
+    if(options->compress == COMPR_FAST || options->compress == COMPR_BEST) {
+       char *compopt = skip_argument;
+
+#if defined(COMPRESS_BEST_OPT) && defined(COMPRESS_FAST_OPT)
+       if(options->compress == COMPR_BEST) {
+           compopt = COMPRESS_BEST_OPT;
+       } else {
+           compopt = COMPRESS_FAST_OPT;
+       }
+#endif
+       comppid = pipespawn(COMPRESS_PATH, STDIN_PIPE,
+                           &dumpout, &dataf, &mesgf,
+                           COMPRESS_PATH, compopt, NULL);
+       dbprintf(("%s: pid %ld: %s",
+                 debug_prefix_time("-gnutar"), (long)comppid, COMPRESS_PATH));
+       if(compopt != skip_argument) {
+           dbprintf((" %s", compopt));
+       }
+       dbprintf(("\n"));
+    } else {
+       dumpout = dataf;
+       comppid = -1;
+    }
+
+#ifdef GNUTAR_LISTED_INCREMENTAL_DIR                                   /* { */
+#ifdef SAMBA_CLIENT                                                    /* { */
+    if (amdevice[0] == '/' && amdevice[1]=='/')
+       amfree(incrname);
+    else
+#endif                                                                 /* } */
+    {
+       char *basename = NULL;
+       char number[NUM_STR_SIZE];
+       char *s;
+       int ch;
+       char *inputname = NULL;
+       FILE *in = NULL;
+       FILE *out;
+       int baselevel;
+       char *line = NULL;
+
+       basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR,
+                            "/",
+                            host,
+                            disk,
+                            NULL);
+       /*
+        * The loop starts at the first character of the host name,
+        * not the '/'.
+        */
+       s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR);
+       while((ch = *s++) != '\0') {
+           if(ch == '/' || isspace(ch)) s[-1] = '_';
+       }
+
+       ap_snprintf(number, sizeof(number), "%d", level);
+       incrname = vstralloc(basename, "_", number, ".new", NULL);
+       unlink(incrname);
+
+       /*
+        * Open the listed incremental file for the previous level.  Search
+        * backward until one is found.  If none are found (which will also
+        * be true for a level 0), arrange to read from /dev/null.
+        */
+       baselevel = level;
+       while (in == NULL) {
+           if (--baselevel >= 0) {
+               ap_snprintf(number, sizeof(number), "%d", baselevel);
+               inputname = newvstralloc(inputname,
+                                        basename, "_", number, NULL);
+           } else {
+               inputname = newstralloc(inputname, "/dev/null");
+           }
+           if ((in = fopen(inputname, "r")) == NULL) {
+               int save_errno = errno;
+
+               dbprintf(("%s: error opening %s: %s\n",
+                         debug_prefix_time("-gnutar"),
+                         inputname,
+                         strerror(save_errno)));
+               if (baselevel < 0) {
+                   error("error [opening %s: %s]", inputname, strerror(save_errno));
+               }
+           }
+       }
+
+       /*
+        * Copy the previous listed incremental file to the new one.
+        */
+       if ((out = fopen(incrname, "w")) == NULL) {
+           error("error [opening %s: %s]", incrname, strerror(errno));
+       }
+
+       for (; (line = agets(in)) != NULL; free(line)) {
+           if(fputs(line, out) == EOF || putc('\n', out) == EOF) {
+               error("error [writing to %s: %s]", incrname, strerror(errno));
+           }
+       }
+       amfree(line);
+
+       if (ferror(in)) {
+           error("error [reading from %s: %s]", inputname, strerror(errno));
+       }
+       if (fclose(in) == EOF) {
+           error("error [closing %s: %s]", inputname, strerror(errno));
+       }
+       in = NULL;
+       if (fclose(out) == EOF) {
+           error("error [closing %s: %s]", incrname, strerror(errno));
+       }
+       out = NULL;
+
+       dbprintf(("%s: doing level %d dump as listed-incremental",
+                 debug_prefix_time("-gnutar"), level));
+       if(baselevel >= 0) {
+           dbprintf((" from %s", inputname));
+       }
+       dbprintf((" to %s\n", incrname));
+       amfree(inputname);
+       amfree(basename);
+    }
+#endif                                                                 /* } */
+
+    /* find previous dump time */
+
+    if(!start_amandates(0))
+       error("error [opening %s: %s]", AMANDATES_FILE, strerror(errno));
+
+    amdates = amandates_lookup(disk);
+
+    prev_dumptime = EPOCH;
+    for(l = 0; l < level; l++) {
+       if(amdates->dates[l] > prev_dumptime)
+           prev_dumptime = amdates->dates[l];
+    }
+
+    finish_amandates();
+    free_amandates();
+
+    gmtm = gmtime(&prev_dumptime);
+    ap_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);
+
+    dbprintf(("%s: doing level %d dump from date: %s\n",
+             debug_prefix_time("-gnutar"), level, dumptimestr));
+
+    dirname = amname_to_dirname(amdevice);
+
+    cur_dumptime = time(0);
+    cur_level = level;
+    cur_disk = stralloc(disk);
+    indexcmd = vstralloc(
+#ifdef GNUTAR
+                        GNUTAR,
+#else
+                        "tar",
+#endif
+                        " -tf", " -",
+                        " 2>/dev/null",
+                        " | sed", " -e",
+                        " \'s/^\\.//\'",
+                        NULL);
+
+#ifdef SAMBA_CLIENT                                                    /* { */
+    /* Use sambatar if the disk to back up is a PC disk */
+    if (amdevice[0] == '/' && amdevice[1]=='/') {
+       char *sharename = NULL, *user_and_password = NULL, *domain = NULL;
+       char *share = NULL, *subdir = NULL;
+       char *pwtext;
+       char *taropt;
+       int passwdf;
+       int lpass;
+       int pwtext_len;
+       char *pw_fd_env;
+
+       parsesharename(amdevice, &share, &subdir);
+       if (!share) {
+            amfree(share);
+            amfree(subdir);
+            set_pname(error_pn);
+            amfree(error_pn);
+            error("cannot parse disk entry '%s' for share/subdir", disk);
+       }
+       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);
+       }
+       if ((user_and_password = findpass(share, &domain)) == NULL) {
+           if(domain) {
+               memset(domain, '\0', strlen(domain));
+               amfree(domain);
+           }
+           set_pname(error_pn);
+           amfree(error_pn);
+           error("error [invalid samba host or password not found?]");
+       }
+       lpass = strlen(user_and_password);
+       if ((pwtext = strchr(user_and_password, '%')) == NULL) {
+           memset(user_and_password, '\0', lpass);
+           amfree(user_and_password);
+           if(domain) {
+               memset(domain, '\0', strlen(domain));
+               amfree(domain);
+           }
+           set_pname(error_pn);
+           amfree(error_pn);
+           error("password field not \'user%%pass\' for %s", disk);
+       }
+       *pwtext++ = '\0';
+       pwtext_len = strlen(pwtext);
+       if ((sharename = makesharename(share, 0)) == 0) {
+           memset(user_and_password, '\0', lpass);
+           amfree(user_and_password);
+           if(domain) {
+               memset(domain, '\0', strlen(domain));
+               amfree(domain);
+           }
+           set_pname(error_pn);
+           amfree(error_pn);
+           error("error [can't make share name of %s]", share);
+       }
+
+       taropt = stralloc("-T");
+       if(options->exclude_file && options->exclude_file->nb_element == 1) {
+           strappend(taropt, "X");
+       }
+#if SAMBA_VERSION >= 2
+       strappend(taropt, "q");
+#endif
+       strappend(taropt, "c");
+       if (level != 0) {
+           strappend(taropt, "g");
+       } else if (!options->no_record) {
+           strappend(taropt, "a");
+       }
+
+       dbprintf(("%s: backup of %s", debug_prefix_time("-gnutar"), sharename));
+       if (subdir) {
+           dbprintf(("/%s",subdir));
+       }
+       dbprintf(("\n"));
+
+       program->backup_name = program->restore_name = SAMBA_CLIENT;
+       cmd = stralloc(program->backup_name);
+       write_tapeheader();
+
+       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+
+       if (pwtext_len > 0) {
+           pw_fd_env = "PASSWD_FD";
+       } else {
+           pw_fd_env = "dummy_PASSWD_FD";
+       }
+       dumppid = pipespawn(cmd, STDIN_PIPE|PASSWD_PIPE,
+                           &dumpin, &dumpout, &mesgf,
+                           pw_fd_env, &passwdf,
+                           "smbclient",
+                           sharename,
+                           *user_and_password ? "-U" : skip_argument,
+                           *user_and_password ? user_and_password : skip_argument,
+                           "-E",
+                           domain ? "-W" : skip_argument,
+                           domain ? domain : skip_argument,
+#if SAMBA_VERSION >= 2
+                           subdir ? "-D" : skip_argument,
+                           subdir ? subdir : skip_argument,
+#endif
+                           "-d0",
+                           taropt,
+                           "-",
+                           options->exclude_file && options->exclude_file->nb_element == 1 ? options->exclude_file->first->name : skip_argument,
+                           NULL);
+       if(domain) {
+           memset(domain, '\0', strlen(domain));
+           amfree(domain);
+       }
+       if(pwtext_len > 0 && fullwrite(passwdf, pwtext, pwtext_len) < 0) {
+           int save_errno = errno;
+
+           aclose(passwdf);
+           memset(user_and_password, '\0', lpass);
+           amfree(user_and_password);
+           set_pname(error_pn);
+           amfree(error_pn);
+           error("error [password write failed: %s]", strerror(save_errno));
+       }
+       memset(user_and_password, '\0', lpass);
+       amfree(user_and_password);
+       aclose(passwdf);
+       amfree(sharename);
+       amfree(share);
+       amfree(subdir);
+       amfree(taropt);
+       tarpid = dumppid;
+    } else
+#endif                                                                 /* } */
+    {
+       int nb_exclude = 0;
+       int nb_include = 0;
+       char **my_argv;
+       int i = 0;
+       char *file_exclude = NULL;
+       char *file_include = NULL;
+
+       if(options->exclude_file) nb_exclude+=options->exclude_file->nb_element;
+       if(options->exclude_list) nb_exclude+=options->exclude_list->nb_element;
+       if(options->include_file) nb_include+=options->include_file->nb_element;
+       if(options->include_list) nb_include+=options->include_list->nb_element;
+
+       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)));
+
+       cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
+       write_tapeheader();
+
+       start_index(options->createindex, dumpout, mesgf, indexf, indexcmd);
+
+       my_argv[i++] = "gtar";
+       my_argv[i++] = "--create";
+       my_argv[i++] = "--file";
+       my_argv[i++] = "-";
+       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 
+#ifdef ENABLE_GNUTAR_ATIME_PRESERVE
+       /* --atime-preserve causes gnutar to call
+        * utime() after reading files in order to
+        * adjust their atime.  However, utime()
+        * updates the file's ctime, so incremental
+        * dumps will think the file has changed. */
+       my_argv[i++] = "--atime-preserve";
+#endif
+       my_argv[i++] = "--sparse";
+       my_argv[i++] = "--ignore-failed-read";
+       my_argv[i++] = "--totals";
+
+       if(file_exclude) {
+           my_argv[i++] = "--exclude-from";
+           my_argv[i++] = file_exclude;
+       }
+
+       if(file_include) {
+           my_argv[i++] = "--files-from";
+           my_argv[i++] = file_include;
+       }
+       else {
+           my_argv[i++] = ".";
+       }
+       my_argv[i++] = NULL;
+       dumppid = pipespawnv(cmd, STDIN_PIPE,
+                            &dumpin, &dumpout, &mesgf, my_argv);
+       tarpid = dumppid;
+       amfree(file_exclude);
+       amfree(file_include);
+       amfree(my_argv);
+    }
+    dbprintf(("%s: %s: pid %ld\n",
+             debug_prefix_time("-gnutar"),
+             cmd,
+             (long)dumppid));
+
+    amfree(dirname);
+    amfree(cmd);
+    amfree(indexcmd);
+    amfree(error_pn);
+
+    /* close the write ends of the pipes */
+
+    aclose(dumpin);
+    aclose(dumpout);
+    aclose(dataf);
+    aclose(mesgf);
+    if (options->createindex)
+       aclose(indexf);
+}
+
+static void end_backup(goterror)
+int goterror;
+{
+    if(!options->no_record && !goterror) {
+#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+      if (incrname != NULL && strlen(incrname) > 4) {
+        char *nodotnew;
+       
+       nodotnew = stralloc(incrname);
+        nodotnew[strlen(nodotnew)-4] = '\0';
+        if (rename(incrname, nodotnew) != 0) {
+            error("error [renaming %s to %s: %s]", 
+                 incrname, nodotnew, strerror(errno));
+       }
+       amfree(nodotnew);
+       amfree(incrname);
+      }
+#endif
+
+        if(!start_amandates(1))
+           error("error [opening %s: %s]", AMANDATES_FILE, strerror(errno));
+       amandates_updateone(cur_disk, cur_level, cur_dumptime);
+       finish_amandates();
+       free_amandates();
+    }
+}
+
+backup_program_t gnutar_program = {
+  "GNUTAR",
+#ifdef GNUTAR
+  GNUTAR, GNUTAR,
+#else
+  "gtar", "gtar",
+#endif
+  re_table, start_backup, end_backup
+};
diff --git a/client-src/sendbackup-krb4.c b/client-src/sendbackup-krb4.c
new file mode 100644 (file)
index 0000000..25a6ec2
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991,1993 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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * sendbackup-krb4.c - those bits of sendbackup code that deal with encrypting
+ *                    data streams over the network.  Even though these just
+ *                    call the underlying DES routines, the U.S. government
+ *                    considers this a munition.  Go figure.
+ */
+#include "krb4-security.h"
+#include "sendbackup-krb4.h"
+
+/*
+ * NOTE:  This symbol must be the same as DATABUF_SIZE in
+ * server-src/dumper-krb4.c
+ * so that the encrypt/decrypt routines are working on the same sized buffers.
+ * Really, this should be moved out of dumper.c so that both programs can use
+ * the same symbol.  Hopefully that can be done later.  This is good enough
+ * to get encryption working for now...
+ *
+ *                  - Chris Ross (cross@uu.net)  4-Jun-1998
+ */
+#define        DATABUF_SIZE    DISK_BLOCK_BYTES
+
+void kencrypt_stream()
+{
+    char *bp, buffer[DATABUF_SIZE];
+    int rdsize, wrsize, left;
+    des_key_schedule sched;
+    int l, n;
+
+    des_key_sched(session_key, sched);
+
+    while(1) {
+       /* read a block, taking into account short reads */
+       left = DATABUF_SIZE;
+       bp = buffer;
+       while(left) {
+           if((rdsize = read(0, bp, left)) == -1)
+               error("kencrypt: read error: %s", strerror(errno));
+           if(rdsize == 0) break;
+           left -= rdsize;
+           bp += rdsize;
+       }
+       if(bp == buffer) break; /* end of file */
+
+       if(bp < buffer+DATABUF_SIZE)
+           memset(bp,0,left);
+
+       des_pcbc_encrypt(buffer, buffer, DATABUF_SIZE, sched, session_key,
+                        DES_ENCRYPT);
+
+       for(l = 0, n = DATABUF_SIZE; l < n; l += wrsize) {
+           if((wrsize = write(1, buffer + l, n - l)) < 0) {
+               error("kencrypt: write error: %s", strerror(errno));
+           }
+       }
+    }
+}
diff --git a/client-src/sendbackup-krb4.h b/client-src/sendbackup-krb4.h
new file mode 100644 (file)
index 0000000..6d7ca30
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991,1993 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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * sendbackup-krb4.h - those bits of sendbackup defines that deal with 
+ *                    encrypting data streams over the network.  Even
+ *                    though these just call the underlying DES
+ *                    routines, the U.S. government considers this a
+ *                    munition.  Go figure.
+ */
+
+#if !defined(SENDBACKUP_KRB4_H)
+#define        SENDBACKUP_KRB4_H
+
+#include "krb4-security.h"
+
+#define KEY_PIPE       3
+
+int encpid;
+
+void kencrypt_stream();
+
+    /* modification by BIS@BBN 4/25/2003:
+     * with the option processing changes in amanda 2.4.4, must change
+     * the conditional from kencrypt to options->kencrypt */
+#define NAUGHTY_BITS                                                         \
+    if(options->kencrypt) {                                                  \
+       int encinf;                                                           \
+       encpid = pipefork(kencrypt_stream,"kencrypt",&encinf,dataf,mesgf);    \
+       dataf = encinf;                                                       \
+    }                                                                        \
+    else                                                                     \
+       encpid = -1;
+
+#endif
diff --git a/client-src/sendbackup.c b/client-src/sendbackup.c
new file mode 100644 (file)
index 0000000..fd71862
--- /dev/null
@@ -0,0 +1,976 @@
+/*
+ * 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: sendbackup.c,v 1.44.2.9.4.4.2.16 2004/01/14 12:59:12 martinea Exp $
+ *
+ * common code for the sendbackup-* programs.
+ */
+
+#include "amanda.h"
+#include "sendbackup.h"
+#include "clock.h"
+#include "pipespawn.h"
+#include "amfeatures.h"
+#include "stream.h"
+#include "arglist.h"
+#include "getfsent.h"
+#include "version.h"
+
+#define TIMEOUT 30
+
+int comppid = -1;
+int dumppid = -1;
+int tarpid = -1;
+int encpid = -1;
+int indexpid = -1;
+char *errorstr = NULL;
+
+int data_socket, data_port, dataf;
+int mesg_socket, mesg_port, mesgf;
+int index_socket, index_port, indexf;
+
+option_t *options;
+
+#ifdef KRB4_SECURITY
+#include "sendbackup-krb4.h"
+#else                                  /* I'd tell you what this does */
+#define NAUGHTY_BITS                   /* but then I'd have to kill you */
+#endif
+
+long dump_size = -1;
+
+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;
+
+/* 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));
+
+
+char *optionstr(option_t *options)
+{
+    static char *optstr = NULL;
+    char *compress_opt = "";
+    char *record_opt = "";
+    char *bsd_opt = "";
+    char *krb4_opt = "";
+    char *kencrypt_opt = "";
+    char *index_opt = "";
+    char *exclude_file_opt;
+    char *exclude_list_opt;
+    char *exc = NULL;
+    sle_t *excl;
+
+    if(options->compress == COMPR_BEST)
+       compress_opt = "compress-best;";
+    else if(options->compress == COMPR_FAST)
+       compress_opt = "compress-fast;";
+    else if(options->compress == COMPR_SERVER_BEST)
+       compress_opt = "srvcomp-best;";
+    else if(options->compress == COMPR_SERVER_FAST)
+       compress_opt = "srvcomp-fast;";
+    if(options->no_record) record_opt = "no-record;";
+    if(options->bsd_auth) bsd_opt = "bsd-auth;";
+#ifdef KRB4_SECURITY
+    if(options->krb4_auth) krb4_opt = "krb4-auth;";
+    if(options->kencrypt) kencrypt_opt = "kencrypt;";
+#endif
+    if(options->createindex) index_opt = "index;";
+
+    exclude_file_opt = stralloc("");
+    if(options->exclude_file) {
+       for(excl = options->exclude_file->first; excl != NULL; excl=excl->next){
+           exc = newvstralloc(exc, "exclude-file=", excl->name, ";", NULL);
+           strappend(exclude_file_opt, exc);
+       }
+    }
+    exclude_list_opt = stralloc("");
+    if(options->exclude_list) {
+       for(excl = options->exclude_list->first; excl != NULL; excl=excl->next){
+           exc = newvstralloc(exc, "exclude-list=", excl->name, ";", NULL);
+           strappend(exclude_list_opt, exc);
+       }
+    }
+    optstr = newvstralloc(optstr,
+                         compress_opt,
+                         record_opt,
+                         bsd_opt,
+                         krb4_opt,
+                         kencrypt_opt,
+                         index_opt,
+                         exclude_file_opt,
+                         exclude_list_opt,
+                         NULL);
+    return optstr;
+}
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    int interactive = 0;
+    int level, mesgpipe[2];
+    char *prog, *disk, *amdevice, *dumpdate, *stroptions;
+    char *line = NULL;
+    char *err_extra = NULL;
+    char *s;
+    int i;
+    int ch;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    int fd;
+
+    /* initialize */
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+#ifdef KRB4_SECURITY
+       if (fd != KEY_PIPE)     /* XXX interface needs to be fixed */
+#endif
+               close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("sendbackup");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    interactive = (argc > 1 && strcmp(argv[1],"-t") == 0);
+    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
+    dbopen();
+    startclock();
+    dbprintf(("%s: version %s\n", argv[0], version()));
+
+    our_features = am_init_feature_set();
+    our_feature_string = am_feature_to_string(our_features);
+
+    if(interactive) {
+       /*
+        * In interactive (debug) mode, the backup data is sent to
+        * /dev/null and none of the network connections back to driver
+        * programs on the tape host are set up.  The index service is
+        * run and goes to stdout.
+        */
+       fprintf(stderr, "%s: running in interactive test mode\n", get_pname());
+       fflush(stderr);
+    }
+
+    prog = NULL;
+    disk = NULL;
+    amdevice = NULL;
+    dumpdate = NULL;
+    stroptions = NULL;
+
+    /* parse dump request */
+
+    for(; (line = agets(stdin)) != NULL; free(line)) {
+       if(interactive) {
+           fprintf(stderr, "%s> ", get_pname());
+           fflush(stderr);
+       }
+#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';
+           }
+           continue;
+       }
+
+       if (prog != NULL) {
+           err_extra = "multiple requests";
+           goto err;
+       }
+
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);                 /* find the program name */
+       if(ch == '\0') {
+           err_extra = "no program name";
+           goto err;                           /* no program name */
+       }
+       prog = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       prog = stralloc(prog);
+
+       skip_whitespace(s, ch);                 /* find the disk name */
+       if(ch == '\0') {
+           err_extra = "no disk name";
+           goto err;                           /* no disk name */
+       }
+       amfree(disk);
+       disk = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       disk = stralloc(disk);
+
+       skip_whitespace(s, ch);                 /* find the device or level */
+       if (ch == '\0') {
+           err_extra = "bad level";
+           goto err;
+       }
+
+       if(!isdigit((int)s[-1])) {
+           amfree(amdevice);
+           amdevice = s - 1;
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';
+           amdevice = stralloc(amdevice);
+           skip_whitespace(s, ch);             /* find level number */
+       }
+       else {
+           amdevice = stralloc(disk);
+       }
+
+                                               /* find the level number */
+       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           err_extra = "bad level";
+           goto err;                           /* bad level */
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);                 /* find the dump date */
+       if(ch == '\0') {
+           err_extra = "no dumpdate";
+           goto err;                           /* no dumpdate */
+       }
+       amfree(dumpdate);
+       dumpdate = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       dumpdate = stralloc(dumpdate);
+
+       skip_whitespace(s, ch);                 /* find the options keyword */
+       if(ch == '\0') {
+           err_extra = "no options";
+           goto err;                           /* no options */
+       }
+#define sc "OPTIONS "
+       if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           err_extra = "no OPTIONS keyword";
+           goto err;                           /* no options */
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+       skip_whitespace(s, ch);                 /* find the options string */
+       if(ch == '\0') {
+           err_extra = "bad options string";
+           goto err;                           /* no options */
+       }
+       amfree(stroptions);
+       stroptions = stralloc(s - 1);
+    }
+    amfree(line);
+
+    dbprintf(("  parsed request as: program `%s'\n", prog));
+    dbprintf(("                     disk `%s'\n", disk));
+    dbprintf(("                     device `%s'\n", amdevice));
+    dbprintf(("                     level %d\n", level));
+    dbprintf(("                     since %s\n", dumpdate));
+    dbprintf(("                     options `%s'\n", stroptions));
+
+    for(i = 0; programs[i] != NULL; i++) {
+       if (strcmp(programs[i]->name, prog) == 0) {
+           break;
+       }
+    }
+    if (programs[i] == NULL) {
+       error("ERROR [%s: unknown program %s]", get_pname(), prog);
+    }
+    program = programs[i];
+
+    options = parse_options(stroptions, disk, amdevice, g_options->features, 0);
+
+#ifdef KRB4_SECURITY
+    /* modification by BIS@BBN 4/25/2003:
+     * with the option processing changes in amanda 2.4.4, must change
+     * the conditional from krb4_auth to options->krb4_auth */
+    if(options->krb4_auth) {
+       if(read(KEY_PIPE, session_key, sizeof session_key) 
+          != sizeof session_key) {
+         error("ERROR [%s: could not read session key]", get_pname());
+       }
+    }
+#endif
+
+    if(!interactive) {
+      data_socket = stream_server(&data_port, STREAM_BUFSIZE, -1);
+      if(data_socket < 0) {
+       error("ERROR [%s: could not create data socket: %s]",
+             get_pname(), strerror(errno));
+      }
+      mesg_socket = stream_server(&mesg_port, -1, -1);
+      if(mesg_socket < 0) {
+       error("ERROR [%s: could not create mesg socket: %s]",
+             get_pname(), strerror(errno));
+      }
+    }
+    if (!interactive && options->createindex) {
+      index_socket = stream_server(&index_port, -1, -1);
+      if(index_socket < 0) {
+       error("ERROR [%s: could not create index socket: %s]",
+             get_pname(), strerror(errno));
+      }
+    } else {
+      index_port = -1;
+    }
+
+    printf("CONNECT DATA %d MESG %d INDEX %d\n",
+          data_port, mesg_port, index_port);
+    printf("OPTIONS ");
+    if(am_has_feature(g_options->features, fe_rep_options_features)) {
+       printf("features=%s;", our_feature_string);
+    }
+    if(am_has_feature(g_options->features, fe_rep_options_hostname)) {
+       printf("hostname=%s;", g_options->hostname);
+    }
+    if(am_has_feature(g_options->features, fe_rep_options_sendbackup_options)) {
+       printf("%s", optionstr(options));
+    }
+    printf("\n");
+    fflush(stdout);
+    freopen("/dev/null", "w", stdout);
+
+    if (options->createindex)
+      dbprintf(("%s: waiting for connect on %d, then %d, then %d\n",
+               debug_prefix_time(NULL), data_port, mesg_port, index_port));
+    else
+      dbprintf(("%s: waiting for connect on %d, then %d\n",
+               debug_prefix_time(NULL), data_port, mesg_port));
+
+    if(interactive) {
+      if((dataf = open("/dev/null", O_RDWR)) < 0) {
+       error("ERROR [%s: open of /dev/null for debug data stream: %s]",
+             get_pname(), strerror(errno));
+      }
+      mesgf = 2;
+    } else {
+      dataf = stream_accept(data_socket, TIMEOUT, -1, -1);
+      if(dataf == -1) {
+       dbprintf(("%s: timeout on data port %d\n",
+                 debug_prefix_time(NULL), data_port));
+      }
+      mesgf = stream_accept(mesg_socket, TIMEOUT, -1, -1);
+      if(mesgf == -1) {
+        dbprintf(("%s: timeout on mesg port %d\n",
+                 debug_prefix_time(NULL), mesg_port));
+      }
+    }
+    if(interactive) {
+      indexf = 1;
+    } else if (options->createindex) {
+      indexf = stream_accept(index_socket, TIMEOUT, -1, -1);
+      if (indexf == -1) {
+       dbprintf(("%s: timeout on index port %d\n",
+                 debug_prefix_time(NULL), index_port));
+      }
+    }
+
+    if(!interactive) {
+      if(dataf == -1 || mesgf == -1 || (options->createindex && indexf == -1)) {
+        dbclose();
+        exit(1);
+      }
+    }
+
+    dbprintf(("%s: got all connections\n", debug_prefix_time(NULL)));
+
+#ifdef KRB4_SECURITY
+    if(!interactive) {
+      /* modification by BIS@BBN 4/25/2003:
+       * with the option processing changes in amanda 2.4.4, must change
+       * the conditional from krb4_auth to options->krb4_auth */
+      if (options->krb4_auth) {
+        if(kerberos_handshake(dataf, session_key) == 0) {
+           dbprintf(("%s: kerberos_handshake on data socket failed\n",
+                     debug_prefix_time(NULL)));
+           dbclose();
+           exit(1);
+        } else {
+           dbprintf(("%s: kerberos_handshake on data socket succeeded\n",
+                     debug_prefix_time(NULL)));
+
+       }
+
+        if(kerberos_handshake(mesgf, session_key) == 0) {
+           dbprintf(("%s: kerberos_handshake on mesg socket failed\n",
+                     debug_prefix_time(NULL)));
+           dbclose();
+           exit(1);
+        } else {
+           dbprintf(("%s: kerberos_handshake on mesg socket succeeded\n",
+                     debug_prefix_time(NULL)));
+
+       }
+
+        dbprintf(("%s: kerberos handshakes succeeded!\n",
+                 debug_prefix_time(NULL)));
+      }
+    }
+#endif
+
+    if(!interactive) {
+      /* redirect stderr */
+      if(dup2(mesgf, 2) == -1) {
+         dbprintf(("%s: error redirecting stderr: %s\n",
+                   debug_prefix(NULL), strerror(errno)));
+         dbclose();
+         exit(1);
+      }
+    }
+
+    if(pipe(mesgpipe) == -1) {
+      error("error [opening mesg pipe: %s]", strerror(errno));
+    }
+
+    program->start_backup(g_options->hostname, disk, amdevice, level, dumpdate,
+                         dataf, mesgpipe[1], indexf);
+    parse_backup_messages(mesgpipe[0]);
+
+    amfree(prog);
+    amfree(disk);
+    amfree(amdevice);
+    amfree(dumpdate);
+    amfree(stroptions);
+    amfree(our_feature_string);
+    am_release_feature_set(our_features);
+    our_features = NULL;
+    am_release_feature_set(g_options->features);
+    g_options->features = NULL;
+    amfree(g_options->hostname);
+    amfree(g_options->str);
+    amfree(g_options);
+
+    dbclose();
+
+    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 0;
+
+ err:
+    printf("FORMAT ERROR IN REQUEST PACKET\n");
+    dbprintf(("%s: REQ packet is bogus%s%s\n",
+             debug_prefix_time(NULL),
+             err_extra ? ": " : "",
+             err_extra ? err_extra : ""));
+    dbclose();
+    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.
+ */
+{
+    if(pid == dumppid) return program->backup_name;
+    if(pid == comppid) return "compress";
+    if(pid == encpid)  return "kencrypt";
+    if(pid == indexpid) return "index";
+    return "unknown";
+}
+
+
+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.
+ */
+{
+    char *thiserr = NULL;
+    char *str;
+    int ret, sig, rc;
+    char number[NUM_STR_SIZE];
+
+    str = childstr(pid);
+
+    if(WIFSIGNALED(w)) {
+       ret = 0;
+       rc = sig = WTERMSIG(w);
+    } else {
+       sig = 0;
+       rc = ret = WEXITSTATUS(w);
+    }
+
+    if(pid == indexpid) {
+       /*
+        * Treat an index failure (other than signal) as a "STRANGE"
+        * rather than an error so the dump goes ahead and gets processed
+        * but the failure is noted.
+        */
+       if(ret != 0) {
+           fprintf(stderr, "? %s returned %d\n", str, ret);
+           rc = 0;
+       }
+    }
+
+#ifndef HAVE_GZIP
+    if(pid == comppid) {
+       /*
+        * compress returns 2 sometimes, but it is ok.
+        */
+       if(ret == 2) {
+           rc = 0;
+       }
+    }
+#endif
+
+#ifdef DUMP_RETURNS_1
+    if(pid == dumppid && tarpid == -1) {
+        /*
+        * Ultrix dump returns 1 sometimes, but it is ok.
+        */
+        if(ret == 1) {
+           rc = 0;
+       }
+    }
+#endif
+
+#ifdef IGNORE_TAR_ERRORS
+    if(pid == tarpid) {
+       /*
+        * tar bitches about active filesystems, but we do not care.
+        */
+        if(ret == 2) {
+           rc = 0;
+       }
+    }
+#endif
+
+    if(rc == 0) {
+       return 0;                               /* normal exit */
+    }
+
+    if(ret == 0) {
+       ap_snprintf(number, sizeof(number), "%d", sig);
+       thiserr = vstralloc(str, " got signal ", number, NULL);
+    } else {
+       ap_snprintf(number, sizeof(number), "%d", ret);
+       thiserr = vstralloc(str, " returned ", number, NULL);
+    }
+
+    if(errorstr) {
+       strappend(errorstr, ", ");
+       strappend(errorstr, thiserr);
+       amfree(thiserr);
+    } else {
+       errorstr = thiserr;
+       thiserr = NULL;
+    }
+    return 1;
+}
+
+
+/* Send header info to the message file.
+*/
+void write_tapeheader()
+{
+    fprintf(stderr, "%s: info BACKUP=%s\n", get_pname(), program->backup_name);
+
+    fprintf(stderr, "%s: info RECOVER_CMD=", get_pname());
+    if (options->compress == COMPR_FAST || options->compress == COMPR_BEST)
+       fprintf(stderr, "%s %s |", UNCOMPRESS_PATH,
+#ifdef UNCOMPRESS_OPT
+               UNCOMPRESS_OPT
+#else
+               ""
+#endif
+               );
+
+    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",
+                       get_pname(), COMPRESS_SUFFIX);
+
+    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;
+{
+    int pid, inpipe[2];
+
+    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));
+    }
+
+    switch(pid = fork()) {
+    case -1:
+       error("error [fork %s: %s]", fname, strerror(errno));
+    default:   /* parent process */
+       aclose(inpipe[0]);      /* close input side of pipe */
+       *stdinfd = inpipe[1];
+       break;
+    case 0:            /* child process */
+       aclose(inpipe[1]);      /* close output side of pipe */
+
+       if(dup2(inpipe[0], 0) == -1) {
+           error("error [dup2 0 %s: dup2 in: %s]", fname, strerror(errno));
+       }
+       if(dup2(stdoutfd, 1) == -1) {
+           error("error [dup2 1 %s: dup2 out: %s]", fname, strerror(errno));
+       }
+       if(dup2(stderrfd, 2) == -1) {
+           error("error [dup2 2 %s: dup2 err: %s]", fname, strerror(errno));
+       }
+
+       func();
+       exit(0);
+       /* NOTREACHED */
+    }
+    return pid;
+}
+
+void parse_backup_messages(mesgin)
+int mesgin;
+{
+    int goterror, wpid;
+    amwait_t retstat;
+    char *line;
+
+    goterror = 0;
+    amfree(errorstr);
+
+    for(; (line = areads(mesgin)) != NULL; free(line)) {
+       process_dumpline(line);
+    }
+
+    if(errno) {
+       error("error [read mesg pipe: %s]", strerror(errno));
+    }
+
+    while((wpid = wait(&retstat)) != -1) {
+       if(check_status(wpid, retstat)) goterror = 1;
+    }
+
+    if(errorstr) {
+       error("error [%s]", errorstr);
+    } else if(dump_size == -1) {
+       error("error [no backup size line]");
+    }
+
+    program->end_backup(goterror);
+
+    fprintf(stderr, "%s: size %ld\n", get_pname(), dump_size);
+    fprintf(stderr, "%s: end\n", get_pname());
+}
+
+
+double first_num P((char *str));
+
+double first_num(str)
+char *str;
+/*
+ * Returns the value of the first integer in a string.
+ */
+{
+    char *num;
+    int ch;
+    double d;
+
+    ch = *str++;
+    while(ch && !isdigit(ch)) ch = *str++;
+    num = str - 1;
+    while(isdigit(ch) || ch == '.') ch = *str++;
+    str[-1] = '\0';
+    d = atof(num);
+    str[-1] = ch;
+    return d;
+}
+
+static void process_dumpline(str)
+char *str;
+{
+    regex_t *rp;
+    char *type;
+    char startchr;
+
+    for(rp = program->re_table; rp->regex != NULL; rp++) {
+       if(match(rp->regex, str)) {
+           break;
+       }
+    }
+    if(rp->typ == DMP_SIZE) {
+       dump_size = (long)((first_num(str) * rp->scale + 1023.0)/1024.0);
+    }
+    switch(rp->typ) {
+    case DMP_NORMAL:
+       type = "normal";
+       startchr = '|';
+       break;
+    case DMP_STRANGE:
+       type = "strange";
+       startchr = '?';
+       break;
+    case DMP_SIZE:
+       type = "size";
+       startchr = '|';
+       break;
+    case DMP_ERROR:
+       type = "error";
+       startchr = '?';
+       break;
+    default:
+       /*
+        * Should never get here.
+        */
+       type = "unknown";
+       startchr = '!';
+       break;
+    }
+    dbprintf(("%s: %3d: %7s(%c): %s\n",
+             debug_prefix_time(NULL),
+             rp->srcline,
+             type,
+             startchr,
+             str));
+    fprintf(stderr, "%c %s\n", startchr, 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;
+
+static void index_closed(sig)
+int sig;
+{
+  index_finished = 1;
+}
+
+void save_fd(fd, min)
+int *fd, min;
+{
+  int origfd = *fd;
+
+  while (*fd >= 0 && *fd < min) {
+    int newfd = dup(*fd);
+    if (newfd == -1)
+      dbprintf(("%s: unable to save file descriptor [%s]\n",
+               debug_prefix(NULL), strerror(errno)));
+    *fd = newfd;
+  }
+  if (origfd != *fd)
+    dbprintf(("%s: dupped file descriptor %i to %i\n",
+             debug_prefix(NULL), origfd, *fd));
+}
+
+void start_index(createindex, input, mesg, index, cmd)
+int createindex, input, mesg, index;
+char *cmd;
+{
+  struct sigaction act, oact;
+  int pipefd[2];
+  FILE *pipe_fp;
+  int exitcode;
+
+  if (!createindex)
+    return;
+
+  if (pipe(pipefd) != 0) {
+    error("creating index pipe: %s", strerror(errno));
+  }
+
+  switch(indexpid = fork()) {
+  case -1:
+    error("forking index tee process: %s", strerror(errno));
+
+  default:
+    aclose(pipefd[0]);
+    if (dup2(pipefd[1], input) == -1) {
+      error("dup'ping index tee output: %s", strerror(errno));
+    }
+    aclose(pipefd[1]);
+    return;
+
+  case 0:
+    break;
+  }
+
+  /* now in a child process */
+  save_fd(&pipefd[0], 4);
+  save_fd(&index, 4);
+  save_fd(&mesg, 4);
+  save_fd(&input, 4);
+  dup2(pipefd[0], 0);
+  dup2(index, 1);
+  dup2(mesg, 2);
+  dup2(input, 3);
+  for(index = 4; index < FD_SETSIZE; index++) {
+    if (index != dbfd()) {
+      close(index);
+    }
+  }
+
+  /* set up a signal handler for SIGPIPE for when the pipe is finished
+     creating the index file */
+  /* at that point we obviously want to stop writing to it */
+  act.sa_handler = index_closed;
+  sigemptyset(&act.sa_mask);
+  act.sa_flags = 0;
+  if (sigaction(SIGPIPE, &act, &oact) != 0) {
+    error("couldn't set index SIGPIPE handler [%s]", strerror(errno));
+  }
+
+  if ((pipe_fp = popen(cmd, "w")) == NULL) {
+    error("couldn't start index creator [%s]", strerror(errno));
+  }
+
+  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;
+
+    bytes_read = read(0, buffer, sizeof(buffer));
+    if ((bytes_read < 0) && (errno == EINTR))
+      continue;
+
+    if (bytes_read < 0) {
+      error("index tee cannot read [%s]", strerror(errno));
+    }
+
+    if (bytes_read == 0)
+      break; /* finished */
+
+    /* write the stuff to the subprocess */
+    ptr = buffer;
+    bytes_written = 0;
+    while (bytes_read > bytes_written && !index_finished) {
+      just_written = write(fileno(pipe_fp), ptr, bytes_read - bytes_written);
+      if (just_written < 0) {
+         /* the signal handler may have assigned to index_finished
+          * just as we waited for write() to complete. */
+         if (!index_finished) {
+             dbprintf(("%s: index tee cannot write to index creator [%s]\n",
+                       debug_prefix_time(NULL), strerror(errno)));
+             index_finished = 1;
+       }
+      } else {
+       bytes_written += just_written;
+       ptr += just_written;
+      }
+    }
+
+    /* write the stuff to stdout, ensuring none lost when interrupt
+       occurs */
+    ptr = buffer;
+    bytes_written = 0;
+    while (bytes_read > bytes_written) {
+      just_written = write(3, ptr, bytes_read - bytes_written);
+      if ((just_written < 0) && (errno == EINTR))
+       continue;
+      if (just_written < 0) {
+       error("index tee cannot write [%s]", strerror(errno));
+      } else {
+       bytes_written += just_written;
+       ptr += just_written;
+      }
+    }
+  }
+
+  aclose(pipefd[1]);
+
+  /* finished */
+  /* check the exit code of the pipe and moan if not 0 */
+  if ((exitcode = pclose(pipe_fp)) != 0) {
+    dbprintf(("%s: index pipe returned %d\n",
+             debug_prefix_time(NULL), exitcode));
+  } else {
+    dbprintf(("%s: index created successfully\n", debug_prefix_time(NULL)));
+  }
+  pipe_fp = NULL;
+
+  exit(exitcode);
+}
+
+extern backup_program_t dump_program, gnutar_program;
+
+backup_program_t *programs[] = {
+  &dump_program, &gnutar_program, NULL
+};
+
+#ifdef KRB4_SECURITY
+#include "sendbackup-krb4.c"
+#endif
diff --git a/client-src/sendbackup.h b/client-src/sendbackup.h
new file mode 100644 (file)
index 0000000..e20ca0d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * 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: sendbackup.h,v 1.11.4.1.6.3 2002/03/31 21:01:32 jrjackson Exp $
+ *
+ * a few common decls for the sendbackup-* sources
+ */
+#include "amanda.h"
+#include "pipespawn.h"
+#include "client_util.h"
+
+void write_tapeheader P((void));
+
+void start_index P((int createindex, int input, int mesg, 
+                   int index, char *cmd));
+
+/*
+ * Dump output lines are scanned for two types of regex matches.
+ *
+ * First, there are some cases, unfortunately, where dump detects an
+ * error but does not return an error code.  We would like to bring these
+ * errors to the attention of the operators anyway.  
+ *
+ * Second, we attempt to determine what dump thinks its output size is.
+ * This is cheaper than putting a filter between dump and compress just
+ * to determine the output size.  The re_size table contains regexes to
+ * match the size output by various vendors' dump programs.  Some vendors
+ * output the number in Kbytes, some in 512-byte blocks.  Whenever an
+ * entry in re_size matches, the first integer in the dump line is
+ * multiplied by the scale field to get the dump size.
+ */
+
+typedef enum { 
+    DMP_NORMAL, DMP_STRANGE, DMP_SIZE, DMP_ERROR
+} dmpline_t;
+
+typedef struct regex_s {
+    char *regex;
+    int srcline;
+    int scale;                  /* only used for size lines */
+    dmpline_t typ;
+} regex_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, tarpid;
+extern int indexpid;
+extern option_t *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));
+} backup_program_t;
+
+extern backup_program_t *programs[], *program;
+
diff --git a/client-src/sendsize.c b/client-src/sendsize.c
new file mode 100644 (file)
index 0000000..c13f875
--- /dev/null
@@ -0,0 +1,1610 @@
+/*
+ * 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: sendsize.c,v 1.97.2.13.4.6.2.23 2003/10/24 20:38:23 kovert Exp $
+ *
+ * send estimated backup sizes using dump
+ */
+
+#include "amanda.h"
+#include "pipespawn.h"
+#include "amfeatures.h"
+#include "amandates.h"
+#include "clock.h"
+#include "util.h"
+#include "getfsent.h"
+#include "version.h"
+#include "client_util.h"
+
+#ifdef SAMBA_CLIENT
+#include "findpass.h"
+#endif
+
+#ifdef HAVE_SETPGID
+#  define SETPGRP      setpgid(getpid(), getpid())
+#  define SETPGRP_FAILED() do {                                                \
+    dbprintf(("setpgid(%ld,%ld) failed: %s\n",                         \
+             (long)getpid(), (long)getpid(), strerror(errno)));        \
+} while(0)
+
+#else /* () line 0 */
+#if defined(SETPGRP_VOID)
+#  define SETPGRP      setpgrp()
+#  define SETPGRP_FAILED() do {                                                \
+    dbprintf(("setpgrp() failed: %s\n", strerror(errno)));             \
+} while(0)
+
+#else
+#  define SETPGRP      setpgrp(0, getpid())
+#  define SETPGRP_FAILED() do {                                                \
+    dbprintf(("setpgrp(0,%ld) failed: %s\n",                           \
+             (long)getpid(), strerror(errno)));                        \
+} while(0)
+
+#endif
+#endif
+
+typedef struct level_estimates_s {
+    time_t dumpsince;
+    int estsize;
+    int needestimate;
+} level_estimate_t;
+
+typedef struct disk_estimates_s {
+    struct disk_estimates_s *next;
+    char *amname;
+    char *amdevice;
+    char *dirname;
+    char *program;
+    int spindle;
+    pid_t child;
+    int done;
+    option_t *options;
+    level_estimate_t est[DUMP_LEVELS];
+} disk_estimates_t;
+
+disk_estimates_t *est_list;
+
+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));
+void add_diskest P((char *disk, char *amdevice, int level, int spindle,
+                   char *prog, 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 generic_calc_estimates P((disk_estimates_t *));
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    int level, spindle;
+    char *prog, *disk, *amdevice, *dumpdate;
+    option_t *options = NULL;
+    disk_estimates_t *est;
+    disk_estimates_t *est1;
+    disk_estimates_t *est_prev;
+    char *line = NULL;
+    char *s, *fp;
+    int ch;
+    char *err_extra = NULL;
+    int fd;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    int done;
+    int need_wait;
+    int dumpsrunning;
+
+
+    /* initialize */
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("sendsize");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = (ERR_INTERACTIVE|ERR_SYSLOG);
+    dbopen();
+    startclock();
+    dbprintf(("%s: version %s\n", get_pname(), version()));
+
+    our_features = am_init_feature_set();
+    our_feature_string = am_feature_to_string(our_features);
+
+    set_debug_prefix_pid(getpid());
+
+    /* handle all service requests */
+
+    start_amandates(0);
+
+    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';
+           }
+
+           printf("OPTIONS ");
+           if(am_has_feature(g_options->features, fe_rep_options_features)) {
+               printf("features=%s;", our_feature_string);
+           }
+           if(am_has_feature(g_options->features, fe_rep_options_maxdumps)) {
+               printf("maxdumps=%d;", g_options->maxdumps);
+           }
+           if(am_has_feature(g_options->features, fe_rep_options_hostname)) {
+               printf("hostname=%s;", g_options->hostname);
+           }
+           printf("\n");
+           fflush(stdout);
+           continue;
+       }
+
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);                 /* find the program name */
+       if(ch == '\0') {
+           err_extra = "no program name";
+           goto err;                           /* no program name */
+       }
+       prog = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the disk name */
+       if(ch == '\0') {
+           err_extra = "no disk name";
+           goto err;                           /* no disk name */
+       }
+       disk = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the device or level */
+       if (ch == '\0') {
+           err_extra = "bad level";
+           goto err;
+       }
+       if(!isdigit((int)s[-1])) {
+           fp = s - 1;
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';
+           amdevice = stralloc(fp);
+           skip_whitespace(s, ch);             /* find level number */
+       }
+       else {
+           amdevice = stralloc(disk);
+       }
+
+                                               /* find the level number */
+       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           err_extra = "bad level";
+           goto err;                           /* bad level */
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);                 /* find the dump date */
+       if(ch == '\0') {
+           err_extra = "no dumpdate";
+           goto err;                           /* no dumpdate */
+       }
+       dumpdate = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       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";
+               goto err;                       /* bad spindle */
+           }
+           skip_integer(s, ch);
+
+           skip_whitespace(s, ch);             /* find the exclusion list */
+           if(ch != '\0') {
+               if(strncmp(s-1, "OPTIONS |;",10) == 0) {
+                   options = parse_options(s + 8,
+                                           disk,
+                                           amdevice,
+                                           g_options->features,
+                                           0);
+               }
+               else {
+                   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 */
+                   }
+               }
+           }
+           else {
+               options = alloc(sizeof(option_t));
+               init_options(options);
+           }
+       }
+
+       add_diskest(disk, amdevice, level, spindle, prog, options);
+       amfree(amdevice);
+    }
+    amfree(line);
+
+    finish_amandates();
+    free_amandates();
+
+    dumpsrunning = 0;
+    need_wait = 0;
+    done = 0;
+    while(! done) {
+       done = 1;
+       /*
+        * See if we need to wait for a child before we can do anything
+        * else in this pass.
+        */
+       if(need_wait) {
+           pid_t child_pid;
+           amwait_t child_status;
+           int exit_code;
+
+           need_wait = 0;
+           dbprintf(("%s: waiting for any estimate child: %d running\n",
+                     debug_prefix_time(NULL), dumpsrunning));
+           child_pid = wait(&child_status);
+           if(child_pid == -1) {
+               error("wait failed: %s", strerror(errno));
+           }
+           if(WIFSIGNALED(child_status)) {
+               dbprintf(("%s: child %ld terminated with signal %d\n",
+                         debug_prefix_time(NULL),
+                         (long) child_pid, WTERMSIG(child_status)));
+           } else {
+               exit_code = WEXITSTATUS(child_status);
+               if(exit_code == 0) {
+                   dbprintf(("%s: child %ld terminated normally\n",
+                             debug_prefix_time(NULL), (long) child_pid));
+               } else {
+                   dbprintf(("%s: child %ld terminated with code %d\n",
+                             debug_prefix_time(NULL),
+                             (long) child_pid, exit_code));
+               }
+           }
+           /*
+            * Find the child and mark it done.
+            */
+           for(est = est_list; est != NULL; est = est->next) {
+               if(est->child == child_pid) {
+                   break;
+               }
+           }
+           if(est == NULL) {
+               dbprintf(("%s: unexpected child %ld\n",
+                         debug_prefix_time(NULL), (long)child_pid));
+           } else {
+               est->done = 1;
+               est->child = 0;
+               dumpsrunning--;
+           }
+       }
+       /*
+        * If we are already running the maximum number of children
+        * go back and wait until one of them finishes.
+        */
+       if(dumpsrunning >= g_options->maxdumps) {
+           done = 0;
+           need_wait = 1;
+           continue;                           /* have to wait first */
+       }
+       /*
+        * Find a new child to start.
+        */
+       for(est = est_list; est != NULL; est = est->next) {
+           if(est->done == 0) {
+               done = 0;                       /* more to do */
+           }
+           if(est->child != 0 || est->done) {
+               continue;                       /* child is running or done */
+           }
+           /*
+            * Make sure there is no spindle conflict.
+            */
+           if(est->spindle != -1) {
+               for(est1 = est_list; est1 != NULL; est1 = est1->next) {
+                   if(est1->child == 0 || est == est1 || est1->done) {
+                       /*
+                        * Ignore anything not yet started, ourself,
+                        * and anything completed.
+                        */
+                       continue;
+                   }
+                   if(est1->spindle == est->spindle) {
+                       break;                  /* oops -- they match */
+                   }
+               }
+               if(est1 != NULL) {
+                   continue;                   /* spindle conflict */
+               }
+           }
+           break;                              /* start this estimate */
+       }
+       if(est == NULL) {
+           if(dumpsrunning > 0) {
+               need_wait = 1;                  /* nothing to do but wait */
+           }
+       } else {
+           done = 0;
+           if((est->child = fork()) == 0) {
+               set_debug_prefix_pid(getpid());
+               calc_estimates(est);            /* child does the estimate */
+               exit(0);
+           } else if(est->child == -1) {
+               error("calc_estimates fork failed: %s", strerror(errno));
+           }
+           dumpsrunning++;                     /* parent */
+       }
+    }
+
+    est_prev = NULL;
+    for(est = est_list; est != NULL; est = est->next) {
+       free_estimates(est);
+       amfree(est_prev);
+       est_prev = est;
+    }
+    amfree(est_prev);
+    amfree(our_feature_string);
+    am_release_feature_set(our_features);
+    our_features = NULL;
+    am_release_feature_set(g_options->features);
+    g_options->features = NULL;
+    amfree(g_options->str);
+    amfree(g_options->hostname);
+    amfree(g_options);
+
+    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
+    }
+
+    dbclose();
+    return 0;
+ err:
+    printf("FORMAT ERROR IN REQUEST PACKET\n");
+    dbprintf(("%s: REQ packet is bogus%s%s\n",
+             debug_prefix_time(NULL),
+             err_extra ? ": " : "",
+             err_extra ? err_extra : ""));
+    dbclose();
+    return 1;
+}
+
+
+void add_diskest(disk, amdevice, level, spindle, prog, options)
+char *disk, *amdevice, *prog;
+int level, spindle;
+option_t *options;
+{
+    disk_estimates_t *newp, *curp;
+    amandates_t *amdp;
+    int dumplev, estlev;
+    time_t dumpdate;
+
+    for(curp = est_list; curp != NULL; curp = curp->next) {
+       if(strcmp(curp->amname, disk) == 0) {
+           /* already have disk info, just note the level request */
+           curp->est[level].needestimate = 1;
+           if(options) {
+               free_sl(options->exclude_file);
+               free_sl(options->exclude_list);
+               free_sl(options->include_file);
+               free_sl(options->include_list);
+               amfree(options->str);
+               amfree(options);
+           }
+           return;
+       }
+    }
+
+    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->amdevice = stralloc(amdevice);
+    newp->dirname = amname_to_dirname(newp->amdevice);
+    newp->program = stralloc(prog);
+    newp->spindle = spindle;
+    newp->est[level].needestimate = 1;
+    newp->options = options;
+
+    /* fill in dump-since dates */
+
+    amdp = amandates_lookup(newp->amname);
+
+    newp->est[0].dumpsince = EPOCH;
+    for(dumplev = 0; dumplev < DUMP_LEVELS; dumplev++) {
+       dumpdate = amdp->dates[dumplev];
+       for(estlev = dumplev+1; estlev < DUMP_LEVELS; estlev++) {
+           if(dumpdate > newp->est[estlev].dumpsince)
+               newp->est[estlev].dumpsince = dumpdate;
+       }
+    }
+}
+
+
+void free_estimates(est)
+disk_estimates_t *est;
+{
+    amfree(est->amname);
+    amfree(est->amdevice);
+    amfree(est->dirname);
+    amfree(est->program);
+    if(est->options) {
+       free_sl(est->options->exclude_file);
+       free_sl(est->options->exclude_list);
+       free_sl(est->options->include_file);
+       free_sl(est->options->include_list);
+       amfree(est->options->str);
+       amfree(est->options);
+    }
+}
+
+/*
+ * ------------------------------------------------------------------------
+ *
+ */
+
+void calc_estimates(est)
+disk_estimates_t *est;
+{
+    dbprintf(("%s: calculating for amname '%s', dirname '%s', spindle %d\n",
+             debug_prefix_time(NULL),
+             est->amname, est->dirname, est->spindle));
+
+#ifndef USE_GENERIC_CALCSIZE
+    if(strcmp(est->program, "DUMP") == 0)
+       dump_calc_estimates(est);
+    else
+#endif
+#ifdef SAMBA_CLIENT
+      if (strcmp(est->program, "GNUTAR") == 0 &&
+         est->amdevice[0] == '/' && est->amdevice[1] == '/')
+       smbtar_calc_estimates(est);
+      else
+#endif
+#ifdef GNUTAR
+       if (strcmp(est->program, "GNUTAR") == 0)
+         gnutar_calc_estimates(est);
+       else
+#endif
+         generic_calc_estimates(est);
+
+    dbprintf(("%s: done with amname '%s', dirname '%s', spindle %d\n",
+             debug_prefix_time(NULL),
+             est->amname, est->dirname, est->spindle));
+}
+
+void generic_calc_estimates(est)
+disk_estimates_t *est;
+{
+    char *cmd;
+    char *argv[DUMP_LEVELS*2+10];
+    char number[NUM_STR_SIZE];
+    int i, level, argc, calcpid;
+
+    cmd = vstralloc(libexecdir, "/", "calcsize", versionsuffix(), NULL);
+
+    argc = 0;
+    argv[argc++] = stralloc("calcsize");
+    argv[argc++] = stralloc(est->program);
+#ifdef BUILTIN_EXCLUDE_SUPPORT
+    if(est->exclude && *est->exclude) {
+       argv[argc++] = stralloc("-X");
+       argv[argc++] = stralloc(est->exclude);
+    }
+#endif
+    argv[argc++] = stralloc(est->amdevice);
+    argv[argc++] = stralloc(est->dirname);
+
+    dbprintf(("%s: running cmd: %s", debug_prefix_time(NULL), argv[0]));
+    for(i=0; i<argc; ++i)
+       dbprintf((" %s", argv[i]));
+
+    for(level = 0; level < DUMP_LEVELS; level++) {
+       if(est->est[level].needestimate) {
+           ap_snprintf(number, sizeof(number), "%d", level);
+           argv[argc++] = stralloc(number); 
+           dbprintf((" %s", number));
+           ap_snprintf(number, sizeof(number),
+                       "%ld", (long)est->est[level].dumpsince);
+           argv[argc++] = stralloc(number); 
+           dbprintf((" %s", number));
+       }
+    }
+    argv[argc] = NULL;
+    dbprintf(("\n"));
+
+    fflush(stderr); fflush(stdout);
+
+    switch(calcpid = fork()) {
+    case -1:
+        error("%s: fork returned: %s", cmd, strerror(errno));
+    default:
+        break;
+    case 0:
+       execve(cmd, argv, safe_env());
+       error("%s: execve returned: %s", cmd, strerror(errno));
+       exit(1);
+    }
+    for(i = 0; i < argc; i++) {
+       amfree(argv[i]);
+    }
+    amfree(cmd);
+
+    dbprintf(("%s: waiting for %s \"%s\" child\n",
+             debug_prefix_time(NULL), argv[0], est->amdevice));
+    wait(NULL);
+    dbprintf(("%s: after %s \"%s\" wait\n",
+             debug_prefix_time(NULL), argv[0], est->amdevice));
+}
+
+
+/*
+ * ------------------------------------------------------------------------
+ *
+ */
+
+/* local functions */
+void dump_calc_estimates P((disk_estimates_t *est));
+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 handle_dumpline P((char *str));
+double first_num P((char *str));
+
+void dump_calc_estimates(est)
+disk_estimates_t *est;
+{
+    int level;
+    long 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);
+
+           amflock(1, "size");
+
+           fseek(stdout, (off_t)0, SEEK_SET);
+
+           printf("%s %d SIZE %ld\n", est->amname, level, size);
+           fflush(stdout);
+
+           amfunlock(1, "size");
+       }
+    }
+}
+
+#ifdef SAMBA_CLIENT
+void smbtar_calc_estimates(est)
+disk_estimates_t *est;
+{
+    int level;
+    long 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));
+           size = getsize_smbtar(est->amname, est->amdevice, level, est->options);
+
+           amflock(1, "size");
+
+           fseek(stdout, (off_t)0, SEEK_SET);
+
+           printf("%s %d SIZE %ld\n", est->amname, level, size);
+           fflush(stdout);
+
+           amfunlock(1, "size");
+       }
+    }
+}
+#endif
+
+#ifdef GNUTAR
+void gnutar_calc_estimates(est)
+disk_estimates_t *est;
+{
+  int level;
+  long 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));
+         size = getsize_gnutar(est->amname, est->amdevice, level,
+                               est->options, est->est[level].dumpsince);
+
+         amflock(1, "size");
+
+         fseek(stdout, (off_t)0, SEEK_SET);
+
+         printf("%s %d SIZE %ld\n", est->amname, level, size);
+         fflush(stdout);
+
+         amfunlock(1, "size");
+      }
+  }
+}
+#endif
+
+typedef struct regex_s {
+    char *regex;
+    int scale;
+} regex_t;
+
+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: 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 */
+    {"backup: estimated [0-9][0-9]* tape blocks", 1024},             /* AIX */
+    {"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 */
+
+#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 */
+#endif
+#endif
+
+#ifdef 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 */
+#endif
+
+#ifdef XFSDUMP
+    {"xfsdump: estimated dump size: [0-9][0-9]* bytes", 1},  /* Irix 6.2 xfs */
+#endif
+
+#ifdef USE_QUICK_AND_DIRTY_ESTIMATES
+    {"amqde estimate: [0-9][0-9]* kb", 1024},                      /* amqde */
+#endif
+    
+#ifdef GNUTAR
+    {"Total bytes written: [0-9][0-9]*", 1},               /* Gnutar client */
+#endif
+
+#ifdef SAMBA_CLIENT
+#if SAMBA_VERSION >= 2
+#define SAMBA_DEBUG_LEVEL "0"
+    {"Total number of bytes: [0-9][0-9]*", 1},                  /* Samba du */
+#else
+#define SAMBA_DEBUG_LEVEL "3"
+    {"Total bytes listed: [0-9][0-9]*", 1},                    /* Samba dir */
+#endif
+#endif
+
+    { NULL, 0 }
+};
+
+
+long getsize_dump(disk, amdevice, level, options)
+    char *disk, *amdevice;
+    int level;
+    option_t *options;
+{
+    int pipefd[2], nullfd, stdoutfd, killctl[2];
+    pid_t dumppid;
+    long size;
+    FILE *dumpout;
+    char *dumpkeys = NULL;
+    char *device = NULL;
+    char *fstype = NULL;
+    char *cmd = NULL;
+    char *name = NULL;
+    char *line = NULL;
+    char *rundump_cmd = NULL;
+    char level_str[NUM_STR_SIZE];
+    int s;
+    times_t start_time;
+
+    ap_snprintf(level_str, sizeof(level_str), "%d", level);
+
+    device = amname_to_devname(amdevice);
+    fstype = amname_to_fstype(amdevice);
+
+    dbprintf(("%s: calculating for device '%s' with '%s'\n",
+             debug_prefix_time(NULL), device, fstype));
+
+    cmd = vstralloc(libexecdir, "/rundump", versionsuffix(), NULL);
+    rundump_cmd = stralloc(cmd);
+
+    stdoutfd = nullfd = open("/dev/null", O_RDWR);
+    pipefd[0] = pipefd[1] = killctl[0] = killctl[1] = -1;
+    pipe(pipefd);
+
+#ifdef XFSDUMP                                         /* { */
+#ifdef DUMP                                            /* { */
+    if (strcmp(fstype, "xfs") == 0)
+#else                                                  /* } { */
+    if (1)
+#endif                                                 /* } */
+    {
+        name = stralloc(" (xfsdump)");
+       dbprintf(("%s: running \"%s%s -F -J -l %s - %s\"\n",
+                 debug_prefix_time(NULL), cmd, name, level_str, device));
+    }
+    else
+#endif                                                 /* } */
+#ifdef VXDUMP                                          /* { */
+#ifdef DUMP                                            /* { */
+    if (strcmp(fstype, "vxfs") == 0)
+#else                                                  /* } { */
+    if (1)
+#endif                                                 /* } */
+    {
+#ifdef USE_RUNDUMP
+        name = stralloc(" (vxdump)");
+#else
+       name = stralloc("");
+       cmd = newstralloc(cmd, VXDUMP);
+#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));
+    }
+    else
+#endif                                                 /* } */
+#ifdef VDUMP                                           /* { */
+#ifdef DUMP                                            /* { */
+    if (strcmp(fstype, "advfs") == 0)
+#else                                                  /* } { */
+    if (1)
+#endif                                                 /* } */
+    {
+       name = stralloc(" (vdump)");
+       amfree(device);
+       device = amname_to_dirname(amdevice);
+       dumpkeys = vstralloc(level_str, "b", "f", NULL);
+       dbprintf(("%s: running \"%s%s %s 60 - %s\"\n",
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+    }
+    else
+#endif                                                 /* } */
+#ifdef DUMP                                            /* { */
+    if (1) {
+# ifdef USE_RUNDUMP                                    /* { */
+#  ifdef AIX_BACKUP                                    /* { */
+       name = stralloc(" (backup)");
+#  else                                                        /* } { */
+       name = vstralloc(" (", DUMP, ")", NULL);
+#  endif                                               /* } */
+# else                                                 /* } { */
+       name = stralloc("");
+       cmd = newstralloc(cmd, DUMP);
+# 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));
+# else                                                 /* } { */
+       dumpkeys = vstralloc(level_str,
+#  ifdef HAVE_DUMP_ESTIMATE                            /* { */
+                            HAVE_DUMP_ESTIMATE,
+#  endif                                               /* } */
+#  ifdef HAVE_HONOR_NODUMP                             /* { */
+                            "h",
+#  endif                                               /* } */
+                            "s", "f", NULL);
+
+#  ifdef HAVE_DUMP_ESTIMATE
+       stdoutfd = pipefd[1];
+#  endif
+
+#  ifdef HAVE_HONOR_NODUMP                             /* { */
+       dbprintf(("%s: running \"%s%s %s 0 1048576 - %s\"\n",
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+#  else                                                        /* } { */
+       dbprintf(("%s: running \"%s%s %s 1048576 - %s\"\n",
+                 debug_prefix_time(NULL), cmd, name, dumpkeys, device));
+#  endif                                               /* } */
+# endif                                                        /* } */
+    }
+    else
+#endif                                                 /* } */
+    {
+       error("no dump program available");
+    }
+
+    pipe(killctl);
+
+    start_time = curclock();
+    switch(dumppid = fork()) {
+    case -1:
+       dbprintf(("%s: cannot fork for killpgrp: %s\n",
+                 debug_prefix(NULL), strerror(errno)));
+       amfree(dumpkeys);
+       amfree(cmd);
+       amfree(rundump_cmd);
+       amfree(device);
+       amfree(name);
+       return -1;
+    default:
+       break; 
+    case 0:    /* child process */
+       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)));
+       else {
+           switch(fork()) {
+           case -1:
+               dbprintf(("%s: fork failed, trying without killpgrp\n",
+                         debug_prefix(NULL)));
+               break;
+
+           default:
+           {
+               char *killpgrp_cmd = vstralloc(libexecdir, "/killpgrp",
+                                              versionsuffix(), NULL);
+               dbprintf(("%s: running %s\n",
+                         debug_prefix_time(NULL), killpgrp_cmd));
+               dup2(killctl[0], 0);
+               dup2(nullfd, 1);
+               dup2(nullfd, 2);
+               close(pipefd[0]);
+               close(pipefd[1]);
+               close(killctl[1]);
+               close(nullfd);
+               execle(killpgrp_cmd, killpgrp_cmd, (char *)0, safe_env());
+               dbprintf(("%s: cannot execute %s: %s\n",
+                         debug_prefix(NULL), killpgrp_cmd, strerror(errno)));
+               exit(-1);
+           }
+
+           case 0:  /* child process */
+               break;
+           }
+       }
+
+       dup2(nullfd, 0);
+       dup2(stdoutfd, 1);
+       dup2(pipefd[1], 2);
+       aclose(pipefd[0]);
+       if (killctl[0] != -1)
+           aclose(killctl[0]);
+       if (killctl[1] != -1)
+           aclose(killctl[1]);
+
+#ifdef XFSDUMP
+#ifdef DUMP
+       if (strcmp(fstype, "xfs") == 0)
+#else
+       if (1)
+#endif
+           execle(cmd, "xfsdump", "-F", "-J", "-l", level_str, "-", device,
+                  (char *)0, safe_env());
+       else
+#endif
+#ifdef VXDUMP
+#ifdef DUMP
+       if (strcmp(fstype, "vxfs") == 0)
+#else
+       if (1)
+#endif
+           execle(cmd, "vxdump", dumpkeys, "1048576", "-", device, (char *)0,
+                  safe_env());
+       else
+#endif
+#ifdef VDUMP
+#ifdef DUMP
+       if (strcmp(fstype, "advfs") == 0)
+#else
+       if (1)
+#endif
+           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());
+# 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));
+       }
+    }
+
+    amfree(dumpkeys);
+    amfree(rundump_cmd);
+
+    aclose(pipefd[1]);
+    if (killctl[0] != -1)
+       aclose(killctl[0]);
+    dumpout = fdopen(pipefd[0],"r");
+
+    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+       dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+       size = handle_dumpline(line);
+       if(size > -1) {
+           amfree(line);
+           if((line = agets(dumpout)) != NULL) {
+               dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+           }
+           break;
+       }
+    }
+    amfree(line);
+
+    dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
+    dbprintf(("%s: estimate time for %s level %d: %s\n",
+             debug_prefix(NULL),
+             disk,
+             level,
+             walltime_str(timessub(curclock(), start_time))));
+    if(size == -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)));
+    } else if(size == 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)));
+    }
+    dbprintf(("%s: estimate size for %s level %d: %ld KB\n",
+             debug_prefix(NULL),
+             disk,
+             level,
+             size));
+
+    if (killctl[1] != -1) {
+       dbprintf(("%s: asking killpgrp to terminate\n",
+                 debug_prefix_time(NULL)));
+       aclose(killctl[1]);
+       for(s = 5; s > 0; --s) {
+           sleep(1);
+           if (waitpid(dumppid, NULL, WNOHANG) != -1)
+               goto terminated;
+       }
+    }
+    
+    /*
+     * First, try to kill the dump process nicely.  If it ignores us
+     * for several seconds, hit it harder.
+     */
+    dbprintf(("%s: sending SIGTERM to process group %ld\n",
+             debug_prefix_time(NULL), (long)dumppid));
+    if (kill(-dumppid, SIGTERM) == -1) {
+       dbprintf(("%s: kill failed: %s\n",
+                 debug_prefix(NULL), strerror(errno)));
+    }
+    /* Now check whether it dies */
+    for(s = 5; s > 0; --s) {
+       sleep(1);
+       if (waitpid(dumppid, NULL, WNOHANG) != -1)
+           goto terminated;
+    }
+
+    dbprintf(("%s: sending SIGKILL to process group %ld\n",
+             debug_prefix_time(NULL), (long)dumppid));
+    if (kill(-dumppid, SIGKILL) == -1) {
+       dbprintf(("%s: kill failed: %s\n",
+                 debug_prefix(NULL), strerror(errno)));
+    }
+    for(s = 5; s > 0; --s) {
+       sleep(1);
+       if (waitpid(dumppid, NULL, WNOHANG) != -1)
+           goto terminated;
+    }
+
+    dbprintf(("%s: waiting for %s%s \"%s\" child\n",
+             debug_prefix_time(NULL), cmd, name, disk));
+    wait(NULL);
+    dbprintf(("%s: after %s%s \"%s\" wait\n",
+             debug_prefix_time(NULL), cmd, name, disk));
+
+ terminated:
+
+    aclose(nullfd);
+    afclose(dumpout);
+
+    amfree(device);
+    amfree(fstype);
+
+    amfree(cmd);
+    amfree(name);
+
+    return size;
+}
+
+#ifdef SAMBA_CLIENT
+long getsize_smbtar(disk, amdevice, level, optionns)
+    char *disk, *amdevice;
+    int level;
+    option_t *optionns;
+{
+    int pipefd = -1, nullfd = -1, passwdfd = -1;
+    int dumppid;
+    long size;
+    FILE *dumpout;
+    char *tarkeys, *sharename, *user_and_password = NULL, *domain = NULL;
+    char *share = NULL, *subdir = NULL;
+    int lpass;
+    char *pwtext;
+    int pwtext_len;
+    char *line;
+    char *pw_fd_env;
+    times_t start_time;
+    char *error_pn = NULL;
+
+    error_pn = stralloc2(get_pname(), "-smbclient");
+
+    parsesharename(amdevice, &share, &subdir);
+    if (!share) {
+       amfree(share);
+       amfree(subdir);
+       set_pname(error_pn);
+       amfree(error_pn);
+       error("cannot parse disk entry '%s' for share/subdir", disk);
+    }
+    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);
+    }
+    if ((user_and_password = findpass(share, &domain)) == NULL) {
+
+       if(domain) {
+           memset(domain, '\0', strlen(domain));
+           amfree(domain);
+       }
+       set_pname(error_pn);
+       amfree(error_pn);
+       error("cannot find password for %s", disk);
+    }
+    lpass = strlen(user_and_password);
+    if ((pwtext = strchr(user_and_password, '%')) == NULL) {
+       memset(user_and_password, '\0', lpass);
+       amfree(user_and_password);
+       if(domain) {
+           memset(domain, '\0', strlen(domain));
+           amfree(domain);
+       }
+       set_pname(error_pn);
+       amfree(error_pn);
+       error("password field not \'user%%pass\' for %s", disk);
+    }
+    *pwtext++ = '\0';
+    pwtext_len = strlen(pwtext);
+    if ((sharename = makesharename(share, 0)) == NULL) {
+       memset(user_and_password, '\0', lpass);
+       amfree(user_and_password);
+       if(domain) {
+           memset(domain, '\0', strlen(domain));
+           amfree(domain);
+       }
+       set_pname(error_pn);
+       amfree(error_pn);
+       error("cannot make share name of %s", share);
+    }
+    nullfd = open("/dev/null", O_RDWR);
+
+#if SAMBA_VERSION >= 2
+    if (level == 0)
+       tarkeys = "archive 0;recurse;du";
+    else
+       tarkeys = "archive 1;recurse;du";
+#else
+    if (level == 0)
+       tarkeys = "archive 0;recurse;dir";
+    else
+       tarkeys = "archive 1;recurse;dir";
+#endif
+
+    start_time = curclock();
+
+    if (pwtext_len > 0) {
+       pw_fd_env = "PASSWD_FD";
+    } else {
+       pw_fd_env = "dummy_PASSWD_FD";
+    }
+    dumppid = pipespawn(SAMBA_CLIENT, STDERR_PIPE|PASSWD_PIPE,
+             &nullfd, &nullfd, &pipefd, 
+             pw_fd_env, &passwdfd,
+             "smbclient",
+             sharename,
+             "-d", SAMBA_DEBUG_LEVEL,
+             *user_and_password ? "-U" : skip_argument,
+             *user_and_password ? user_and_password : skip_argument,
+             "-E",
+             domain ? "-W" : skip_argument,
+             domain ? domain : skip_argument,
+#if SAMBA_VERSION >= 2
+             subdir ? "-D" : skip_argument,
+             subdir ? subdir : skip_argument,
+#endif
+             "-c", tarkeys,
+             NULL);
+    if(domain) {
+       memset(domain, '\0', strlen(domain));
+       amfree(domain);
+    }
+    aclose(nullfd);
+    if(pwtext_len > 0 && fullwrite(passwdfd, pwtext, pwtext_len) < 0) {
+       int save_errno = errno;
+
+       memset(user_and_password, '\0', lpass);
+       amfree(user_and_password);
+       aclose(passwdfd);
+       set_pname(error_pn);
+       amfree(error_pn);
+       error("password write failed: %s", strerror(save_errno));
+    }
+    memset(user_and_password, '\0', lpass);
+    amfree(user_and_password);
+    aclose(passwdfd);
+    amfree(sharename);
+    amfree(share);
+    amfree(subdir);
+    amfree(error_pn);
+    dumpout = fdopen(pipefd,"r");
+
+    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+       dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+       size = handle_dumpline(line);
+       if(size > -1) {
+           amfree(line);
+           if((line = agets(dumpout)) != NULL) {
+               dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+           }
+           break;
+       }
+    }
+    amfree(line);
+
+    dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
+    dbprintf(("%s: estimate time for %s level %d: %s\n",
+             debug_prefix(NULL),
+             disk,
+             level,
+             walltime_str(timessub(curclock(), start_time))));
+    if(size == -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) {
+       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,
+             level,
+             size));
+
+    kill(-dumppid, SIGTERM);
+
+    dbprintf(("%s: waiting for %s \"%s\" child\n",
+             debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+    wait(NULL);
+    dbprintf(("%s: after %s \"%s\" wait\n",
+             debug_prefix_time(NULL), SAMBA_CLIENT, disk));
+
+    afclose(dumpout);
+    pipefd = -1;
+
+    amfree(error_pn);
+
+    return size;
+}
+#endif
+
+#ifdef GNUTAR
+long getsize_gnutar(disk, amdevice, level, options, dumpsince)
+char *disk, *amdevice;
+int level;
+option_t *options;
+time_t dumpsince;
+{
+    int pipefd = -1, nullfd = -1, dumppid;
+    long size = -1;
+    FILE *dumpout = NULL;
+    char *incrname = NULL;
+    char *basename = NULL;
+    char *dirname = NULL;
+    char *inputname = NULL;
+    FILE *in = NULL;
+    FILE *out = NULL;
+    char *line = NULL;
+    char *cmd = NULL;
+    char dumptimestr[80];
+    struct tm *gmtm;
+    int nb_exclude = 0;
+    int nb_include = 0;
+    char **my_argv;
+    int i;
+    char *file_exclude = NULL;
+    char *file_include = NULL;
+    times_t start_time;
+
+    if(options->exclude_file) nb_exclude += options->exclude_file->nb_element;
+    if(options->exclude_list) nb_exclude += options->exclude_list->nb_element;
+    if(options->include_file) nb_include += options->include_file->nb_element;
+    if(options->include_list) nb_include += options->include_list->nb_element;
+
+    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);
+    i = 0;
+
+#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+    {
+       char number[NUM_STR_SIZE];
+       char *s;
+       int ch;
+       int baselevel;
+
+       basename = vstralloc(GNUTAR_LISTED_INCREMENTAL_DIR,
+                            "/",
+                            g_options->hostname,
+                            disk,
+                            NULL);
+       /*
+        * The loop starts at the first character of the host name,
+        * not the '/'.
+        */
+       s = basename + sizeof(GNUTAR_LISTED_INCREMENTAL_DIR);
+       while((ch = *s++) != '\0') {
+           if(ch == '/' || isspace(ch)) s[-1] = '_';
+       }
+
+       ap_snprintf(number, sizeof(number), "%d", level);
+       incrname = vstralloc(basename, "_", number, ".new", NULL);
+       unlink(incrname);
+
+       /*
+        * Open the listed incremental file from the previous level.  Search
+        * backward until one is found.  If none are found (which will also
+        * be true for a level 0), arrange to read from /dev/null.
+        */
+       baselevel = level;
+       while (in == NULL) {
+           if (--baselevel >= 0) {
+               ap_snprintf(number, sizeof(number), "%d", baselevel);
+               inputname = newvstralloc(inputname,
+                                        basename, "_", number, NULL);
+           } else {
+               inputname = newstralloc(inputname, "/dev/null");
+           }
+           if ((in = fopen(inputname, "r")) == NULL) {
+               int save_errno = errno;
+
+               dbprintf(("%s: gnutar: error opening %s: %s\n",
+                         debug_prefix(NULL), inputname, strerror(save_errno)));
+               if (baselevel < 0) {
+                   goto common_exit;
+               }
+           }
+       }
+
+       /*
+        * Copy the previous listed incremental file to the new one.
+        */
+       if ((out = fopen(incrname, "w")) == NULL) {
+           dbprintf(("%s: opening %s: %s\n",
+                     debug_prefix(NULL), incrname, strerror(errno)));
+           goto common_exit;
+       }
+
+       for (; (line = agets(in)) != NULL; free(line)) {
+           if (fputs(line, out) == EOF || putc('\n', out) == EOF) {
+               dbprintf(("%s: writing to %s: %s\n",
+                          debug_prefix(NULL), incrname, strerror(errno)));
+               goto common_exit;
+           }
+       }
+       amfree(line);
+
+       if (ferror(in)) {
+           dbprintf(("%s: reading from %s: %s\n",
+                     debug_prefix(NULL), inputname, strerror(errno)));
+           goto common_exit;
+       }
+       if (fclose(in) == EOF) {
+           dbprintf(("%s: closing %s: %s\n",
+                     debug_prefix(NULL), inputname, strerror(errno)));
+           in = NULL;
+           goto common_exit;
+       }
+       in = NULL;
+       if (fclose(out) == EOF) {
+           dbprintf(("%s: closing %s: %s\n",
+                     debug_prefix(NULL), incrname, strerror(errno)));
+           out = NULL;
+           goto common_exit;
+       }
+       out = NULL;
+
+       amfree(inputname);
+       amfree(basename);
+    }
+#endif
+
+    gmtm = gmtime(&dumpsince);
+    ap_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 USE_QUICK_AND_DIRTY_ESTIMATES
+    ap_snprintf(dumptimestr, sizeof(dumptimestr), "%ld", dumpsince);
+
+    cmd = vstralloc(libexecdir, "/", "amqde", versionsuffix(), NULL);
+
+    my_argv[i++] = vstralloc(libexecdir, "/", "amqde", versionsuffix(), NULL);
+    my_argv[i++] = "-s";
+    my_argv[i++] = dumptimestr;
+    if(file_exclude) { /* at present, this is not used... */
+       my_argv[i++] = "-x";
+       my_argv[i++] = file_exclude;
+    }
+    /* [XXX] need to also consider implementation of --files-from */
+    my_argv[i++] = dirname;
+    my_argv[i++] = NULL;
+#else
+#ifdef GNUTAR
+    cmd = vstralloc(libexecdir, "/", "runtar", versionsuffix(), NULL);
+
+    my_argv[i++] = GNUTAR;
+#else
+    my_argv[i++] = "tar";
+#endif
+    my_argv[i++] = "--create";
+    my_argv[i++] = "--file";
+    my_argv[i++] = "/dev/null";
+    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
+#ifdef ENABLE_GNUTAR_ATIME_PRESERVE
+    /* --atime-preserve causes gnutar to call
+     * utime() after reading files in order to
+     * adjust their atime.  However, utime()
+     * updates the file's ctime, so incremental
+     * dumps will think the file has changed. */
+    my_argv[i++] = "--atime-preserve";
+#endif
+    my_argv[i++] = "--sparse";
+    my_argv[i++] = "--ignore-failed-read";
+    my_argv[i++] = "--totals";
+
+    if(file_exclude) {
+       my_argv[i++] = "--exclude-from";
+       my_argv[i++] = file_exclude;
+    }
+
+    if(file_include) {
+       my_argv[i++] = "--files-from";
+       my_argv[i++] = file_include;
+    }
+    else {
+       my_argv[i++] = ".";
+    }
+#endif /* USE_QUICK_AND_DIRTY_ESTIMATES */
+    my_argv[i++] = NULL;
+
+    start_time = curclock();
+
+    nullfd = open("/dev/null", O_RDWR);
+    dumppid = pipespawnv(cmd, STDERR_PIPE, &nullfd, &nullfd, &pipefd, my_argv);
+    amfree(cmd);
+    amfree(file_exclude);
+    amfree(file_include);
+
+    dumpout = fdopen(pipefd,"r");
+
+    for(size = -1; (line = agets(dumpout)) != NULL; free(line)) {
+       dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+       size = handle_dumpline(line);
+       if(size > -1) {
+           amfree(line);
+           if((line = agets(dumpout)) != NULL) {
+               dbprintf(("%s: %s\n", debug_prefix_time(NULL), line));
+           }
+           break;
+       }
+    }
+    amfree(line);
+
+    dbprintf(("%s: .....\n", debug_prefix_time(NULL)));
+    dbprintf(("%s: estimate time for %s level %d: %s\n",
+             debug_prefix(NULL),
+             disk,
+             level,
+             walltime_str(timessub(curclock(), start_time))));
+    if(size == -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) {
+       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,
+             level,
+             size));
+
+    kill(-dumppid, SIGTERM);
+
+    dbprintf(("%s: waiting for %s \"%s\" child\n",
+             debug_prefix_time(NULL), my_argv[0], disk));
+    wait(NULL);
+    dbprintf(("%s: after %s \"%s\" wait\n",
+             debug_prefix_time(NULL), my_argv[0], disk));
+
+common_exit:
+
+    if (incrname) {
+       unlink(incrname);
+    }
+    amfree(incrname);
+    amfree(basename);
+    amfree(dirname);
+    amfree(inputname);
+    amfree(my_argv);
+
+    aclose(nullfd);
+    afclose(dumpout);
+    afclose(in);
+    afclose(out);
+
+    return size;
+}
+#endif
+
+
+double first_num(str)
+char *str;
+/*
+ * Returns the value of the first integer in a string.
+ */
+{
+    char *start;
+    int ch;
+    double d;
+
+    ch = *str++;
+    while(ch && !isdigit(ch)) ch = *str++;
+    start = str-1;
+    while(isdigit(ch) || (ch == '.')) ch = *str++;
+    str[-1] = '\0';
+    d = atof(start);
+    str[-1] = ch;
+    return d;
+}
+
+
+long handle_dumpline(str)
+char *str;
+/*
+ * Checks the dump output line against the error and size regex tables.
+ */
+{
+    regex_t *rp;
+    double size;
+
+    /* check for size match */
+    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;
+       }
+    }
+    return -1;
+}
diff --git a/client-src/unctime.c b/client-src/unctime.c
new file mode 100644 (file)
index 0000000..d2ee5ea
--- /dev/null
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id: unctime.c,v 1.2 1997/08/27 08:11:44 amcore Exp $ */
+
+#include "amanda.h"
+
+/*
+ * Convert a ctime(3) format string into a system format date.
+ * Return the date thus calculated.
+ *
+ * Return -1 if the string is not in ctime format.
+ */
+
+/*
+ * Offsets into the ctime string to various parts.
+ */
+
+#define        E_MONTH         4
+#define        E_DAY           8
+#define        E_HOUR          11
+#define        E_MINUTE        14
+#define        E_SECOND        17
+#define        E_YEAR          20
+
+static int lookup P((char *));
+
+
+time_t
+unctime(str)
+       char *str;
+{
+       struct tm then;
+       char dbuf[26];
+
+       (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;
+       then.tm_mday = atoi(&dbuf[E_DAY]);
+       then.tm_hour = atoi(&dbuf[E_HOUR]);
+       then.tm_min = atoi(&dbuf[E_MINUTE]);
+       then.tm_sec = atoi(&dbuf[E_SECOND]);
+       then.tm_year = atoi(&dbuf[E_YEAR]) - 1900;
+       then.tm_isdst = -1;
+       return mktime(&then);
+}
+
+static char months[] =
+       "JanFebMarAprMayJunJulAugSepOctNovDec";
+
+static int
+lookup(str)
+       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 -1;
+}
diff --git a/client-src/versionsuffix.c b/client-src/versionsuffix.c
new file mode 100644 (file)
index 0000000..0eb16e5
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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: versionsuffix.c,v 1.6 1998/07/04 00:18:28 oliva Exp $
+ *
+ * prints the (possibly empty) suffix appended to amanda program names
+ */
+#include "amanda.h"
+#include "version.h"
+
+int main()
+{
+       int fd;
+
+       for(fd = 3; fd < 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
+                * descriptor, which in turn might be used as an index into
+                * an array (e.g. an fd_set).
+                */
+               close(fd);
+       }
+
+       set_pname("versionsuffix");
+
+       printf("%s\n", versionsuffix());
+       return 0;
+}
diff --git a/common-src/Makefile.am b/common-src/Makefile.am
new file mode 100644 (file)
index 0000000..0241740
--- /dev/null
@@ -0,0 +1,115 @@
+# Makefile for Amanda library.
+
+lib_LTLIBRARIES =      libamanda.la
+
+REGDIR = ../regex-src
+REGsrcdir = $(srcdir)/$(REGDIR)
+
+INCLUDES = -I$(REGsrcdir)
+
+libamanda_la_SOURCES = \
+       alloc.c         amflock.c       clock.c         debug.c         \
+       dgram.c         error.c         file.c          fileheader.c    \
+       amfeatures.c    match.c                                         \
+       protocol.c      regcomp.c       regerror.c      regexec.c       \
+       regfree.c       security.c      statfs.c        stream.c        \
+       token.c         util.c          versuff.c       version.c       \
+        pipespawn.c    sl.c
+
+libamanda_la_LIBADD =  @LTLIBOBJS@ @LTALLOCA@
+libamanda_la_LDFLAGS =  -release $(VERSION)
+
+noinst_HEADERS =       amanda.h        arglist.h       \
+                       clock.h         dgram.h         \
+                       amfeatures.h    protocol.h      \
+                       statfs.h        stream.h        \
+                       token.h         version.h       \
+                       amregex.h       fileheader.h    \
+                       util.h          pipespawn.h     \
+                       sl.h
+
+STANDARD_COMMON_STUFF_NOT_FILE = \
+       alloc.$(OBJEXT) \
+       clock.$(OBJEXT) \
+       debug.$(OBJEXT) \
+       error.$(OBJEXT) \
+       util.$(OBJEXT)
+
+STANDARD_COMMON_STUFF = \
+       $(STANDARD_COMMON_STUFF_NOT_FILE) \
+       file.$(OBJEXT)
+
+.sh:
+       cat $< > $@
+       chmod a+x $@
+
+EXTRA_PROGRAMS = genversion $(TEST_PROGS)
+
+EXTRA_DIST = krb4-security.c   krb4-security.h
+
+genversion_SOURCES = genversion.c
+genversion_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF) versuff.o
+
+genversion.o: genversion.h
+genversion.h: $(top_builddir)/config.status
+       -rm -f $@ $@.new
+       echo '#define CC "$(CC)"' > $@.new
+       echo '#define BUILT_DATE "'`date`'"' >> $@.new
+       echo '#define BUILT_MACH "'`uname -a || echo UNKNOWN HOST`'"' >> $@.new
+       mv $@.new $@
+
+version.c:     genversion$(EXEEXT)
+       -rm -f version.c
+       ./genversion > version.c
+
+match.@OBJEXT@ match.lo: regex.h
+regcomp.@OBJEXT@ regcomp.lo: regex.h regcomp.ih
+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 \
+               $(REGsrcdir)/regfree.c
+
+# these are used for testing only:
+TEST_PROGS = statfs token file security amfeatures
+
+CLEANFILES = regex.h regcomp.ih engine.ih regerror.ih *.test.c
+
+DISTCLEANFILES = version.c
+
+regex.h: $(REGEXHSRC) $(REGsrcdir)/mkh
+       sh $(REGsrcdir)/mkh -o -i _REGEX_H_ $(REGEXHSRC) >$@
+
+regcomp.ih: $(REGsrcdir)/regcomp.c $(REGsrcdir)/mkh
+       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regcomp.c >$@
+
+engine.ih: $(REGsrcdir)/engine.c $(REGsrcdir)/mkh
+       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/engine.c >$@
+
+regerror.ih: $(REGsrcdir)/regerror.c $(REGsrcdir)/mkh
+       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regerror.c >$@
+
+# used for testing only
+
+statfs_SOURCES = statfs.test.c
+statfs_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+
+token_SOURCES = token.test.c
+token_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+
+file_SOURCES = file.test.c
+file_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF_NOT_FILE)
+
+security_SOURCES = security.test.c
+security_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+
+amfeatures_SOURCES = amfeatures.test.c
+amfeatures_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
diff --git a/common-src/Makefile.in b/common-src/Makefile.in
new file mode 100644 (file)
index 0000000..a562d6e
--- /dev/null
@@ -0,0 +1,762 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 library.
+
+
+SOURCES = $(libamanda_la_SOURCES) $(amfeatures_SOURCES) $(file_SOURCES) $(genversion_SOURCES) $(security_SOURCES) $(statfs_SOURCES) $(token_SOURCES)
+
+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 = :
+host_triplet = @host@
+EXTRA_PROGRAMS = genversion$(EXEEXT) $(am__EXEEXT_1)
+subdir = common-src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(srcdir)/versuff.c.in alloca.c getcwd.c \
+       memmove.c mktime.c snprintf.c strcasecmp.c strerror.c \
+       strftime.c strncasecmp.c strstr.c waitpid.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 = versuff.c
+am__installdirs = "$(DESTDIR)$(libdir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libamanda_la_DEPENDENCIES = @LTLIBOBJS@ @LTALLOCA@
+am_libamanda_la_OBJECTS = alloc.lo amflock.lo clock.lo debug.lo \
+       dgram.lo error.lo file.lo fileheader.lo amfeatures.lo match.lo \
+       protocol.lo regcomp.lo regerror.lo regexec.lo regfree.lo \
+       security.lo statfs.lo stream.lo token.lo util.lo versuff.lo \
+       version.lo pipespawn.lo sl.lo
+libamanda_la_OBJECTS = $(am_libamanda_la_OBJECTS)
+am__EXEEXT_1 = statfs$(EXEEXT) token$(EXEEXT) file$(EXEEXT) \
+       security$(EXEEXT) amfeatures$(EXEEXT)
+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)
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) file.$(OBJEXT)
+amfeatures_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
+am_file_OBJECTS = file.test.$(OBJEXT)
+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) $(am__DEPENDENCIES_3) \
+       versuff.o
+am_security_OBJECTS = security.test.$(OBJEXT)
+security_OBJECTS = $(am_security_OBJECTS)
+security_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
+am_statfs_OBJECTS = statfs.test.$(OBJEXT)
+statfs_OBJECTS = $(am_statfs_OBJECTS)
+statfs_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
+am_token_OBJECTS = token.test.$(OBJEXT)
+token_OBJECTS = $(am_token_OBJECTS)
+token_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/alloca.Plo $(DEPDIR)/getcwd.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/memmove.Plo $(DEPDIR)/mktime.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/snprintf.Plo $(DEPDIR)/strcasecmp.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/strerror.Plo $(DEPDIR)/strftime.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/strncasecmp.Plo $(DEPDIR)/strstr.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/waitpid.Plo ./$(DEPDIR)/alloc.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/amfeatures.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/amfeatures.test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amflock.Plo ./$(DEPDIR)/clock.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/debug.Plo ./$(DEPDIR)/dgram.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/error.Plo ./$(DEPDIR)/file.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/file.test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/fileheader.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/genversion.Po ./$(DEPDIR)/match.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/pipespawn.Plo ./$(DEPDIR)/protocol.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/regcomp.Plo ./$(DEPDIR)/regerror.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/regexec.Plo ./$(DEPDIR)/regfree.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/security.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/security.test.Po ./$(DEPDIR)/sl.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/statfs.Plo ./$(DEPDIR)/statfs.test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/stream.Plo ./$(DEPDIR)/token.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/token.test.Po ./$(DEPDIR)/util.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/version.Plo ./$(DEPDIR)/versuff.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libamanda_la_SOURCES) $(amfeatures_SOURCES) \
+       $(file_SOURCES) $(genversion_SOURCES) $(security_SOURCES) \
+       $(statfs_SOURCES) $(token_SOURCES)
+DIST_SOURCES = $(libamanda_la_SOURCES) $(amfeatures_SOURCES) \
+       $(file_SOURCES) $(genversion_SOURCES) $(security_SOURCES) \
+       $(statfs_SOURCES) $(token_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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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@
+lib_LTLIBRARIES = libamanda.la
+REGDIR = ../regex-src
+REGsrcdir = $(srcdir)/$(REGDIR)
+INCLUDES = -I$(REGsrcdir)
+libamanda_la_SOURCES = \
+       alloc.c         amflock.c       clock.c         debug.c         \
+       dgram.c         error.c         file.c          fileheader.c    \
+       amfeatures.c    match.c                                         \
+       protocol.c      regcomp.c       regerror.c      regexec.c       \
+       regfree.c       security.c      statfs.c        stream.c        \
+       token.c         util.c          versuff.c       version.c       \
+        pipespawn.c    sl.c
+
+libamanda_la_LIBADD = @LTLIBOBJS@ @LTALLOCA@
+libamanda_la_LDFLAGS = -release $(VERSION)
+noinst_HEADERS = amanda.h      arglist.h       \
+                       clock.h         dgram.h         \
+                       amfeatures.h    protocol.h      \
+                       statfs.h        stream.h        \
+                       token.h         version.h       \
+                       amregex.h       fileheader.h    \
+                       util.h          pipespawn.h     \
+                       sl.h
+
+STANDARD_COMMON_STUFF_NOT_FILE = \
+       alloc.$(OBJEXT) \
+       clock.$(OBJEXT) \
+       debug.$(OBJEXT) \
+       error.$(OBJEXT) \
+       util.$(OBJEXT)
+
+STANDARD_COMMON_STUFF = \
+       $(STANDARD_COMMON_STUFF_NOT_FILE) \
+       file.$(OBJEXT)
+
+EXTRA_DIST = krb4-security.c   krb4-security.h
+genversion_SOURCES = genversion.c
+genversion_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF) versuff.o
+REGEXHSRC = $(REGsrcdir)/regex2.h \
+               $(REGsrcdir)/regcomp.c \
+               $(REGsrcdir)/regexec.c \
+               $(REGsrcdir)/regerror.c \
+               $(REGsrcdir)/regfree.c
+
+
+# these are used for testing only:
+TEST_PROGS = statfs token file security amfeatures
+CLEANFILES = regex.h regcomp.ih engine.ih regerror.ih *.test.c
+DISTCLEANFILES = version.c
+
+# used for testing only
+statfs_SOURCES = statfs.test.c
+statfs_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+token_SOURCES = token.test.c
+token_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+file_SOURCES = file.test.c
+file_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF_NOT_FILE)
+security_SOURCES = security.test.c
+security_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+amfeatures_SOURCES = amfeatures.test.c
+amfeatures_LDADD = $(libamanda_la_LIBADD) $(STANDARD_COMMON_STUFF)
+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  common-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  common-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
+versuff.c: $(top_builddir)/config.status $(srcdir)/versuff.c.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+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="`echo $$p | sed -e 's|^.*/||'`"; \
+           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)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         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
+libamanda.la: $(libamanda_la_OBJECTS) $(libamanda_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(libamanda_la_LDFLAGS) $(libamanda_la_OBJECTS) $(libamanda_la_LIBADD) $(LIBS)
+amfeatures$(EXEEXT): $(amfeatures_OBJECTS) $(amfeatures_DEPENDENCIES) 
+       @rm -f amfeatures$(EXEEXT)
+       $(LINK) $(amfeatures_LDFLAGS) $(amfeatures_OBJECTS) $(amfeatures_LDADD) $(LIBS)
+file$(EXEEXT): $(file_OBJECTS) $(file_DEPENDENCIES) 
+       @rm -f file$(EXEEXT)
+       $(LINK) $(file_LDFLAGS) $(file_OBJECTS) $(file_LDADD) $(LIBS)
+genversion$(EXEEXT): $(genversion_OBJECTS) $(genversion_DEPENDENCIES) 
+       @rm -f genversion$(EXEEXT)
+       $(LINK) $(genversion_LDFLAGS) $(genversion_OBJECTS) $(genversion_LDADD) $(LIBS)
+security$(EXEEXT): $(security_OBJECTS) $(security_DEPENDENCIES) 
+       @rm -f security$(EXEEXT)
+       $(LINK) $(security_LDFLAGS) $(security_OBJECTS) $(security_LDADD) $(LIBS)
+statfs$(EXEEXT): $(statfs_OBJECTS) $(statfs_DEPENDENCIES) 
+       @rm -f statfs$(EXEEXT)
+       $(LINK) $(statfs_LDFLAGS) $(statfs_OBJECTS) $(statfs_LDADD) $(LIBS)
+token$(EXEEXT): $(token_OBJECTS) $(token_DEPENDENCIES) 
+       @rm -f token$(EXEEXT)
+       $(LINK) $(token_LDFLAGS) $(token_OBJECTS) $(token_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/alloca.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getcwd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memmove.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mktime.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/snprintf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strcasecmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strftime.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strncasecmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strstr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/waitpid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amfeatures.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amfeatures.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflock.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@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileheader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genversion.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/match.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipespawn.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regcomp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regerror.Plo@am__quote@
+@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)/security.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/security.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statfs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statfs.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/token.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/versuff.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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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 -z "$$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) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(libdir)"; 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:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+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-libtool \
+       mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf $(DEPDIR) ./$(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-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf $(DEPDIR) ./$(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
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libLTLIBRARIES 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-info install-info-am \
+       install-libLTLIBRARIES 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
+
+
+.sh:
+       cat $< > $@
+       chmod a+x $@
+
+genversion.o: genversion.h
+genversion.h: $(top_builddir)/config.status
+       -rm -f $@ $@.new
+       echo '#define CC "$(CC)"' > $@.new
+       echo '#define BUILT_DATE "'`date`'"' >> $@.new
+       echo '#define BUILT_MACH "'`uname -a || echo UNKNOWN HOST`'"' >> $@.new
+       mv $@.new $@
+
+version.c:     genversion$(EXEEXT)
+       -rm -f version.c
+       ./genversion > version.c
+
+match.@OBJEXT@ match.lo: regex.h
+regcomp.@OBJEXT@ regcomp.lo: regex.h regcomp.ih
+regexec.@OBJEXT@ regexec.lo: regex.h engine.ih
+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) >$@
+
+regcomp.ih: $(REGsrcdir)/regcomp.c $(REGsrcdir)/mkh
+       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regcomp.c >$@
+
+engine.ih: $(REGsrcdir)/engine.c $(REGsrcdir)/mkh
+       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/engine.c >$@
+
+regerror.ih: $(REGsrcdir)/regerror.c $(REGsrcdir)/mkh
+       sh $(REGsrcdir)/mkh -o -p $(REGsrcdir)/regerror.c >$@
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
+# 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/common-src/alloc.c b/common-src/alloc.c
new file mode 100644 (file)
index 0000000..07bab02
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * 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: alloc.c,v 1.17.2.1.4.3.2.3 2002/10/27 14:31:18 martinea Exp $
+ *
+ * Memory allocators with error handling.  If the allocation fails,
+ * errordump() is called, relieving the caller from checking the return
+ * code
+ */
+#include "amanda.h"
+#include "arglist.h"
+
+/*
+ *=====================================================================
+ * debug_caller_loc -- keep track of all allocation callers
+ *
+ * char *debug_caller_loc(char *file, int line)
+ *
+ * entry:      file = source file
+ *             line = source line
+ * exit:       a string like "genversion.c@999"
+ *
+ * The debug malloc library has a concept of a call stack that can be used
+ * to fine tune what was running when a particular allocation was done.
+ * We use it to tell who called our various allocation wrappers since
+ * it wouldn't do much good to tell us a problem happened because of
+ * the malloc call in alloc (they are all from there at some point).
+ *
+ * But the library expects the string passed to malloc_enter/malloc_leave
+ * to be static, so we build a linked list of each one we get (there are
+ * not really that many during a given execution).  When we get a repeat
+ * we return the previously allocated string.  For a bit of performance,
+ * we keep the list in least recently used order, which helps because
+ * the calls to us come in pairs (one for malloc_enter and one right
+ * after for malloc_leave).
+ *=====================================================================
+ */
+
+char *
+debug_caller_loc(file, line)
+    char *file;
+    int line;
+{
+    struct loc_str {
+       char *str;
+       struct loc_str *next;
+    };
+    static struct loc_str *root = NULL;
+    struct loc_str *ls, *ls_last;
+    int len;
+    int size;
+    char *p;
+    static char *loc = NULL;
+    static int loc_size = 0;
+
+    if ((p = strrchr(file, '/')) == NULL) {
+       p = file;                               /* keep the whole name */
+    } else {
+       p++;                                    /* just the last path element */
+    }
+
+    len = strlen (p);
+    size = len + 1 + NUM_STR_SIZE + 1;
+    if (size > loc_size) {
+       size = ((size + 64 - 1) / 64) * 64;     /* might as well get a bunch */
+       /*
+        * We should free the previous loc area, but we have marked it
+        * as a non-leak and the library considers it an error to free
+        * such an area, so we just ignore it.  We probably grabbed
+        * enough the first time that this will not even happen.
+        */
+       loc = malloc (size);
+       if (loc == NULL) {
+           return "??";                        /* not much better than abort */
+       }
+       malloc_mark (loc);
+       loc_size = size;
+    }
+
+    strcpy (loc, p);
+    ap_snprintf(loc + len, 1 + NUM_STR_SIZE, "@%d", line);
+
+    for (ls_last = NULL, ls = root; ls != NULL; ls_last = ls, ls = ls->next) {
+       if (strcmp (loc, ls->str) == 0) {
+           break;
+       }
+    }
+
+    if (ls == NULL) {
+       /*
+        * This is a new entry.  Put it at the head of the list.
+        */
+       ls = malloc (sizeof (*ls));
+       if (ls == NULL) {
+           return "??";                        /* not much better than abort */
+       }
+       malloc_mark (ls);
+       size = strlen (loc) + 1;
+       ls->str = malloc (size);
+       if (ls->str == NULL) {
+           free (ls);
+           return "??";                        /* not much better than abort */
+       }
+       malloc_mark (ls->str);
+       strcpy (ls->str, loc);
+       ls->next = root;
+       root = ls;
+    } else if (ls_last != NULL) {
+       /*
+        * This is a repeat and was not at the head of the list.
+        * Unlink it and move it to the front.
+        */
+       ls_last->next = ls->next;
+       ls->next = root;
+       root = ls;
+    } else {
+       /*
+        * This is a repeat but was already at the head of the list,
+        * so nothing else needs to be done.
+        */
+    }
+    return ls->str;
+}
+
+/*
+ *=====================================================================
+ * Save the current source line for vstralloc/newvstralloc.
+ *
+ * int debug_alloc_push (char *s, int l)
+ *
+ * entry:      s = source file
+ *             l = source line
+ * exit:       always zero
+ * 
+ * See the comments in amanda.h about what this is used for.
+ *=====================================================================
+ */
+
+#define        DEBUG_ALLOC_SAVE_MAX    10
+
+static struct {
+       char            *file;
+       int             line;
+} debug_alloc_loc_info[DEBUG_ALLOC_SAVE_MAX];
+static int debug_alloc_ptr = 0;
+
+static char            *saved_file;
+static int             saved_line;
+
+int
+debug_alloc_push (s, l)
+    char *s;
+    int l;
+{
+    debug_alloc_loc_info[debug_alloc_ptr].file = s;
+    debug_alloc_loc_info[debug_alloc_ptr].line = l;
+    debug_alloc_ptr = (debug_alloc_ptr + 1) % DEBUG_ALLOC_SAVE_MAX;
+    return 0;
+}
+
+/*
+ *=====================================================================
+ * Pop the current source line information for vstralloc/newvstralloc.
+ *
+ * int debug_alloc_pop (void)
+ *
+ * entry:      none
+ * exit:       none
+ * 
+ * See the comments in amanda.h about what this is used for.
+ *=====================================================================
+ */
+
+void
+debug_alloc_pop ()
+{
+    debug_alloc_ptr =
+      (debug_alloc_ptr + DEBUG_ALLOC_SAVE_MAX - 1) % DEBUG_ALLOC_SAVE_MAX;
+    saved_file = debug_alloc_loc_info[debug_alloc_ptr].file;
+    saved_line = debug_alloc_loc_info[debug_alloc_ptr].line;
+}
+
+/*
+ * alloc - a wrapper for malloc.
+ */
+void *
+debug_alloc(s, l, size)
+    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)",
+                 s ? s : "(unknown)",
+                 s ? l : -1,
+                 size);
+    }
+    malloc_leave(debug_caller_loc(s, l));
+    return addr;
+}
+
+
+/*
+ * newalloc - free existing buffer and then alloc a new one.
+ */
+void *
+debug_newalloc(s, l, old, size)
+    char *s;
+    int l;
+    void *old;
+    size_t size;
+{
+    char *addr;
+
+    malloc_enter(debug_caller_loc(s, l));
+    addr = debug_alloc(s, l, size);
+    amfree(old);
+    malloc_leave(debug_caller_loc(s, l));
+    return addr;
+}
+
+
+/*
+ * stralloc - copies the given string into newly allocated memory.
+ *            Just like strdup()!
+ */
+char *
+debug_stralloc(s, l, str)
+    char *s;
+    int l;
+    const char *str;
+{
+    char *addr;
+
+    malloc_enter(debug_caller_loc(s, l));
+    addr = debug_alloc(s, l, strlen(str) + 1);
+    strcpy(addr, str);
+    malloc_leave(debug_caller_loc(s, l));
+    return addr;
+}
+
+
+/*
+ * internal_vstralloc - copies up to MAX_STR_ARGS strings into newly
+ * allocated memory.
+ *
+ * The MAX_STR_ARGS limit is purely an efficiency issue so we do not have
+ * to scan the strings more than necessary.
+ */
+
+#define        MAX_VSTRALLOC_ARGS      32
+
+static char *
+internal_vstralloc(str, argp)
+    const char *str;
+    va_list argp;
+{
+    char *next;
+    char *result;
+    int a;
+    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 */
+    }
+
+    a = 0;
+    arg[a] = str;
+    l = strlen(str);
+    total_len = len[a] = l;
+    a++;
+
+    while ((next = arglist_val(argp, char *)) != NULL) {
+       if ((l = strlen(next)) == 0) {
+           continue;                           /* minor optimisation */
+       }
+       if (a >= MAX_VSTRALLOC_ARGS) {
+           errordump("%s@%d: more than %d arg%s to vstralloc",
+                     saved_file ? saved_file : "(unknown)",
+                     saved_file ? saved_line : -1,
+                     MAX_VSTRALLOC_ARGS,
+                     (MAX_VSTRALLOC_ARGS == 1) ? "" : "s");
+       }
+       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];
+    }
+    *next = '\0';
+
+    return result;
+}
+
+
+/*
+ * vstralloc - copies multiple strings into newly allocated memory.
+ */
+arglist_function(char *debug_vstralloc, const char *, str)
+{
+    va_list argp;
+    char *result;
+
+    debug_alloc_pop();
+    malloc_enter(debug_caller_loc(saved_file, saved_line));
+    arglist_start(argp, str);
+    result = internal_vstralloc(str, argp);
+    arglist_end(argp);
+    malloc_leave(debug_caller_loc(saved_file, saved_line));
+    return result;
+}
+
+
+/*
+ * newstralloc - free existing string and then stralloc a new one.
+ */
+char *
+debug_newstralloc(s, l, oldstr, newstr)
+    char *s;
+    int l;
+    char *oldstr;
+    const char *newstr;
+{
+    char *addr;
+
+    malloc_enter(debug_caller_loc(s, l));
+    addr = debug_stralloc(s, l, newstr);
+    amfree(oldstr);
+    malloc_leave(debug_caller_loc(s, l));
+    return addr;
+}
+
+
+/*
+ * newvstralloc - free existing string and then vstralloc a new one.
+ */
+arglist_function1(char *debug_newvstralloc,
+                 char *,
+                 oldstr,
+                 const char *,
+                 newstr)
+{
+    va_list argp;
+    char *result;
+
+    debug_alloc_pop();
+    malloc_enter(debug_caller_loc(saved_file, saved_line));
+    arglist_start(argp, newstr);
+    result = internal_vstralloc(newstr, argp);
+    arglist_end(argp);
+    amfree(oldstr);
+    malloc_leave(debug_caller_loc(saved_file, saved_line));
+    return result;
+}
+
+
+/*
+ * sbuf_man - static buffer manager.
+ *
+ * Manage a bunch of static buffer pointers.
+ */
+void *sbuf_man(e_bufs, ptr)
+    void *e_bufs; /* XXX - I dont think this is right */
+    void *ptr;
+{
+       SBUF2_DEF(1) *bufs;
+       int slot;
+
+       bufs = e_bufs;
+
+       /* try and trap bugs */
+       assert(bufs->magic == SBUF_MAGIC);
+       assert(bufs->max > 0);
+
+       /* initialise first time through */
+       if(bufs->cur == -1)
+               for(slot=0; slot < bufs->max; slot++) {
+                       bufs->bufp[slot] = (void *)0;
+               } 
+
+       /* calculate the next slot */
+       slot = bufs->cur + 1;
+       if (slot >= bufs->max) slot = 0;
+
+       /* free the previous inhabitant */
+       if(bufs->bufp[slot] != (void *)0) free(bufs->bufp[slot]);
+
+       /* store the new one */
+       bufs->bufp[slot] = ptr;
+       bufs->cur = slot;
+
+       return ptr;
+}
+
+
+/*
+ * safe_env - build a "safe" environment list.
+ */
+char **
+safe_env()
+{
+    static char *safe_env_list[] = {
+       "TZ",
+#ifdef NEED_PATH_ENV
+       "PATH",
+#endif
+       NULL
+    };
+
+    /*
+     * If the initial environment pointer malloc fails, set up to
+     * pass back a pointer to the NULL string pointer at the end of
+     * 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))
+    char **envp = safe_env_list + SAFE_ENV_CNT - 1;
+
+    char **p;
+    char **q;
+    char *s;
+    char *v;
+    size_t l1, l2;
+
+    if ((q = (char **)malloc(sizeof(safe_env_list))) != NULL) {
+       envp = q;
+       for (p = safe_env_list; *p != NULL; p++) {
+           if ((v = getenv(*p)) == NULL) {
+               continue;                       /* no variable to dup */
+           }
+           l1 = strlen(*p);                    /* variable name w/o null */
+           l2 = strlen(v) + 1;                 /* include null byte here */
+           if ((s = (char *)malloc(l1 + 1 + l2)) == NULL) {
+               break;                          /* out of memory */
+           }
+           *q++ = s;                           /* save the new pointer */
+           memcpy(s, *p, l1);                  /* left hand side */
+           s += l1;
+           *s++ = '=';
+           memcpy(s, v, l2);                   /* right hand side and null */
+       }
+       *q = NULL;                              /* terminate the list */
+    }
+    return envp;
+}
+
+/*
+ * amtable_alloc -- (re)allocate enough space for some number of elements.
+ *
+ * input:      table -- pointer to pointer to table
+ *             current -- pointer to current number of elements
+ *             elsize -- size of a table element
+ *             count -- desired number of elements
+ *             bump -- round up factor
+ *             init_func -- optional element initialization function
+ * output:     table -- possibly adjusted to point to new table area
+ *             current -- possibly adjusted to new number of elements
+ */
+
+int
+debug_amtable_alloc(s, l, table, current, elsize, count, bump, init_func)
+    char *s;
+    int l;
+    void **table;
+    int *current;
+    size_t elsize;
+    int count;
+    int bump;
+    void (*init_func)(void *);
+{
+    void *table_new;
+    int table_count_new;
+    int i;
+
+    if (count >= *current) {
+       table_count_new = ((count + bump) / bump) * bump;
+       table_new = debug_alloc(s, l, table_count_new * elsize);
+       if (0 != *table) {
+           memcpy(table_new, *table, *current * elsize);
+           free(*table);
+       }
+       *table = table_new;
+       memset(((char *)*table) + *current * elsize,
+              0,
+              (table_count_new - *current) * elsize);
+       if (init_func != NULL) {
+           for (i = *current; i < table_count_new; i++) {
+               (*init_func)(((char *)*table) + i * elsize);
+           }
+       }
+       *current = table_count_new;
+    }
+    return 0;
+}
+
+/*
+ * amtable_free -- release a table.
+ *
+ * input:      table -- pointer to pointer to table
+ *             current -- pointer to current number of elements
+ * output:     table -- possibly adjusted to point to new table area
+ *             current -- possibly adjusted to new number of elements
+ */
+
+void
+amtable_free(table, current)
+    void **table;
+    int *current;
+{
+    amfree(*table);
+    *current = 0;
+}
diff --git a/common-src/alloca.c b/common-src/alloca.c
new file mode 100644 (file)
index 0000000..ad10087
--- /dev/null
@@ -0,0 +1,481 @@
+/* alloca.c -- allocate automatically reclaimed memory
+   (Mostly) portable public-domain implementation -- D A Gwyn
+
+   This implementation of the PWB library alloca function,
+   which is used to allocate space off the run-time stack so
+   that it is automatically reclaimed upon procedure exit,
+   was inspired by discussions with J. Q. Johnson of Cornell.
+   J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+   There are some preprocessor constants that can
+   be defined when compiling for your specific system, for
+   improved efficiency; however, the defaults should be okay.
+
+   The general concept of this implementation is to keep
+   track of all alloca-allocated blocks, and reclaim any
+   that are found to be deeper in the stack than the current
+   invocation.  This heuristic does not reclaim storage as
+   soon as it becomes invalid, but it will do so eventually.
+
+   As a special case, alloca(0) reclaims storage without
+   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
+
+#ifndef HAVE_ALLOCA
+
+/* If compiling with GCC 2, this file's not needed.  */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+   there must be some other way alloca is supposed to work.  */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+   -- this is for usg, in which emacs must undefine static
+   in order to make unexec workable
+   */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+/* If your stack is a linked list of frames, you have to
+   provide an "address metric" ADDRESS_FUNCTION macro.  */
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#define        NULL    0
+
+/* Different portions of Emacs need to call different versions of
+   malloc.  The Emacs executable needs alloca to call xmalloc, because
+   ordinary malloc isn't protected from input signals.  On the other
+   hand, the utilities in lib-src need alloca to call malloc; some of
+   them are very simple, and don't have an xmalloc routine.
+
+   Non-Emacs programs expect this to call use xmalloc.
+
+   Callers below should use malloc.  */
+
+extern pointer malloc ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+   growth for your system; otherwise it will be automatically
+   deduced at run-time.
+
+   STACK_DIRECTION > 0 => grows toward higher addresses
+   STACK_DIRECTION < 0 => grows toward lower addresses
+   STACK_DIRECTION = 0 => direction of growth unknown  */
+
+#ifndef STACK_DIRECTION
+#define        STACK_DIRECTION 0       /* Direction unknown.  */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define        STACK_DIR       STACK_DIRECTION /* Known at compile-time.  */
+
+#else /* STACK_DIRECTION == 0; need run-time code.  */
+
+static int stack_dir;          /* 1 or -1 once known.  */
+#define        STACK_DIR       stack_dir
+
+static void
+find_stack_direction ()
+{
+  static char *addr = NULL;    /* Address of first `dummy', once known.  */
+  auto char dummy;             /* To get stack address.  */
+
+  if (addr == NULL)
+    {                          /* Initial entry.  */
+      addr = ADDRESS_FUNCTION (dummy);
+
+      find_stack_direction (); /* Recurse once.  */
+    }
+  else
+    {
+      /* Second entry.  */
+      if (ADDRESS_FUNCTION (dummy) > addr)
+       stack_dir = 1;          /* Stack grew upward.  */
+      else
+       stack_dir = -1;         /* Stack grew downward.  */
+    }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+   (a) chain together all alloca'ed blocks;
+   (b) keep track of stack depth.
+
+   It is very important that sizeof(header) agree with malloc
+   alignment chunk size.  The following default should work okay.  */
+
+#ifndef        ALIGN_SIZE
+#define        ALIGN_SIZE      sizeof(double)
+#endif
+
+typedef union hdr
+{
+  char align[ALIGN_SIZE];      /* To force sizeof(header).  */
+  struct
+    {
+      union hdr *next;         /* For chaining headers.  */
+      char *deep;              /* For stack depth measure.  */
+    } h;
+} header;
+
+static header *last_alloca_header = NULL;      /* -> last alloca header.  */
+
+/* Return a pointer to at least SIZE bytes of storage,
+   which will be automatically reclaimed upon exit from
+   the procedure that called alloca.  Originally, this space
+   was supposed to be taken from the current stack frame of the
+   caller, but that method cannot be made to work for some
+   implementations of C, for example under Gould's UTX/32.  */
+
+pointer
+alloca (size)
+     unsigned size;
+{
+  auto char probe;             /* Probes stack depth: */
+  register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+  if (STACK_DIR == 0)          /* Unknown growth direction.  */
+    find_stack_direction ();
+#endif
+
+  /* Reclaim garbage, defined as all alloca'd storage that
+     was allocated from deeper in the stack than currently. */
+
+  {
+    register header *hp;       /* Traverses linked list.  */
+
+    for (hp = last_alloca_header; hp != NULL;)
+      if ((STACK_DIR > 0 && hp->h.deep > depth)
+         || (STACK_DIR < 0 && hp->h.deep < depth))
+       {
+         register header *np = hp->h.next;
+
+         free ((pointer) hp);  /* Collect garbage.  */
+
+         hp = np;              /* -> next header.  */
+       }
+      else
+       break;                  /* Rest are not deeper.  */
+
+    last_alloca_header = hp;   /* -> last valid storage.  */
+  }
+
+  if (size == 0)
+    return NULL;               /* No allocation required.  */
+
+  /* Allocate combined header + user data storage.  */
+
+  {
+    register pointer new = malloc (sizeof (header) + size);
+    /* Address of header.  */
+
+    ((header *) new)->h.next = last_alloca_header;
+    ((header *) new)->h.deep = depth;
+
+    last_alloca_header = (header *) new;
+
+    /* User storage begins just after header.  */
+
+    return (pointer) ((char *) new + sizeof (header));
+  }
+}
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+  {
+    long shgrow:32;            /* Number of times stack has grown.  */
+    long shaseg:32;            /* Size of increments to stack.  */
+    long shhwm:32;             /* High water mark of stack.  */
+    long shsize:32;            /* Current size of stack (all segments).  */
+  };
+
+/* The stack segment linkage control information occurs at
+   the high-address end of a stack segment.  (The stack
+   grows from low addresses to high addresses.)  The initial
+   part of the stack segment linkage control information is
+   0200 (octal) words.  This provides for register storage
+   for the routine which overflows the stack.  */
+
+struct stack_segment_linkage
+  {
+    long ss[0200];             /* 0200 overflow words.  */
+    long sssize:32;            /* Number of words in this segment.  */
+    long ssbase:32;            /* Offset to stack base.  */
+    long:32;
+    long sspseg:32;            /* Offset to linkage control of previous
+                                  segment of stack.  */
+    long:32;
+    long sstcpt:32;            /* Pointer to task common address block.  */
+    long sscsnm;               /* Private control structure number for
+                                  microtasking.  */
+    long ssusr1;               /* Reserved for user.  */
+    long ssusr2;               /* Reserved for user.  */
+    long sstpid;               /* Process ID for pid based multi-tasking.  */
+    long ssgvup;               /* Pointer to multitasking thread giveup.  */
+    long sscray[7];            /* Reserved for Cray Research.  */
+    long ssa0;
+    long ssa1;
+    long ssa2;
+    long ssa3;
+    long ssa4;
+    long ssa5;
+    long ssa6;
+    long ssa7;
+    long sss0;
+    long sss1;
+    long sss2;
+    long sss3;
+    long sss4;
+    long sss5;
+    long sss6;
+    long sss7;
+  };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+   returned by the STKSTAT library routine.  */
+struct stk_stat
+  {
+    long now;                  /* Current total stack size.  */
+    long maxc;                 /* Amount of contiguous space which would
+                                  be required to satisfy the maximum
+                                  stack demand to date.  */
+    long high_water;           /* Stack high-water mark.  */
+    long overflows;            /* Number of stack overflow ($STKOFEN) calls.  */
+    long hits;                 /* Number of internal buffer hits.  */
+    long extends;              /* Number of block extensions.  */
+    long stko_mallocs;         /* Block allocations by $STKOFEN.  */
+    long underflows;           /* Number of stack underflow calls ($STKRETN).  */
+    long stko_free;            /* Number of deallocations by $STKRETN.  */
+    long stkm_free;            /* Number of deallocations by $STKMRET.  */
+    long segments;             /* Current number of stack segments.  */
+    long maxs;                 /* Maximum number of stack segments so far.  */
+    long pad_size;             /* Stack pad size.  */
+    long current_address;      /* Current stack segment address.  */
+    long current_size;         /* Current stack segment size.  This
+                                  number is actually corrupted by STKSTAT to
+                                  include the fifteen word trailer area.  */
+    long initial_address;      /* Address of initial segment.  */
+    long initial_size;         /* Size of initial segment.  */
+  };
+
+/* The following structure describes the data structure which trails
+   any stack segment.  I think that the description in 'asdef' is
+   out of date.  I only describe the parts that I am sure about.  */
+
+struct stk_trailer
+  {
+    long this_address;         /* Address of this block.  */
+    long this_size;            /* Size of this block (does not include
+                                  this trailer).  */
+    long unknown2;
+    long unknown3;
+    long link;                 /* Address of trailer block of previous
+                                  segment.  */
+    long unknown5;
+    long unknown6;
+    long unknown7;
+    long unknown8;
+    long unknown9;
+    long unknown10;
+    long unknown11;
+    long unknown12;
+    long unknown13;
+    long unknown14;
+  };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+   I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+  struct stk_stat status;
+  struct stk_trailer *trailer;
+  long *block, size;
+  long result = 0;
+
+  /* We want to iterate through all of the segments.  The first
+     step is to get the stack status structure.  We could do this
+     more quickly and more directly, perhaps, by referencing the
+     $LM00 common block, but I know that this works.  */
+
+  STKSTAT (&status);
+
+  /* Set up the iteration.  */
+
+  trailer = (struct stk_trailer *) (status.current_address
+                                   + status.current_size
+                                   - 15);
+
+  /* There must be at least one stack segment.  Therefore it is
+     a fatal error if "trailer" is null.  */
+
+  if (trailer == 0)
+    abort ();
+
+  /* Discard segments that do not contain our argument address.  */
+
+  while (trailer != 0)
+    {
+      block = (long *) trailer->this_address;
+      size = trailer->this_size;
+      if (block == 0 || size == 0)
+       abort ();
+      trailer = (struct stk_trailer *) trailer->link;
+      if ((block <= address) && (address < (block + size)))
+       break;
+    }
+
+  /* Set the result to the offset in this segment and add the sizes
+     of all predecessor segments.  */
+
+  result = address - block;
+
+  if (trailer == 0)
+    {
+      return result;
+    }
+
+  do
+    {
+      if (trailer->this_size <= 0)
+       abort ();
+      result += trailer->this_size;
+      trailer = (struct stk_trailer *) trailer->link;
+    }
+  while (trailer != 0);
+
+  /* We are done.  Note that if you present a bogus address (one
+     not in any segment), you will get a different number back, formed
+     from subtracting the address of the first block.  This is probably
+     not what you want.  */
+
+  return result;
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+   Determine the number of the cell within the stack,
+   given the address of the cell.  The purpose of this
+   routine is to linearize, in some sense, stack addresses
+   for alloca.  */
+
+static long
+i00afunc (long address)
+{
+  long stkl = 0;
+
+  long size, pseg, this_segment, stack;
+  long result = 0;
+
+  struct stack_segment_linkage *ssptr;
+
+  /* Register B67 contains the address of the end of the
+     current stack segment.  If you (as a subprogram) store
+     your registers on the stack and find that you are past
+     the contents of B67, you have overflowed the segment.
+
+     B67 also points to the stack segment linkage control
+     area, which is what we are really interested in.  */
+
+  stkl = CRAY_STACKSEG_END ();
+  ssptr = (struct stack_segment_linkage *) stkl;
+
+  /* If one subtracts 'size' from the end of the segment,
+     one has the address of the first word of the segment.
+
+     If this is not the first segment, 'pseg' will be
+     nonzero.  */
+
+  pseg = ssptr->sspseg;
+  size = ssptr->sssize;
+
+  this_segment = stkl - size;
+
+  /* It is possible that calling this routine itself caused
+     a stack overflow.  Discard stack segments which do not
+     contain the target address.  */
+
+  while (!(this_segment <= address && address <= stkl))
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+      if (pseg == 0)
+       break;
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      this_segment = stkl - size;
+    }
+
+  result = address - this_segment;
+
+  /* If you subtract pseg from the current end of the stack,
+     you get the address of the previous stack segment's end.
+     This seems a little convoluted to me, but I'll bet you save
+     a cycle somewhere.  */
+
+  while (pseg != 0)
+    {
+#ifdef DEBUG_I00AFUNC
+      fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+      stkl = stkl - pseg;
+      ssptr = (struct stack_segment_linkage *) stkl;
+      size = ssptr->sssize;
+      pseg = ssptr->sspseg;
+      result += size;
+    }
+  return result;
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
+#endif /* not GCC version 2 */
+
+#endif /* ifndef HAVE_ALLOCA */
diff --git a/common-src/amanda.h b/common-src/amanda.h
new file mode 100644 (file)
index 0000000..74be276
--- /dev/null
@@ -0,0 +1,1198 @@
+/*
+ * 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: amanda.h,v 1.66.2.7.4.5.2.14 2004/04/30 12:13:20 martinea Exp $
+ *
+ * the central header file included by all amanda sources
+ */
+#ifndef AMANDA_H
+#define AMANDA_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.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
+ * protected against multiple inclusion, so this can lead to problems.
+ *
+ * Also, some systems put key files in different places, so by including 
+ * everything here the rest of the system is isolated from such things.
+ */
+#ifdef HAVE_ALLOCA_H
+#  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>
+#  define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+#  define dirent direct
+#  define NAMLEN(dirent) (dirent)->d_namlen
+#  if HAVE_SYS_NDIR_H
+#    include <sys/ndir.h>
+#  endif
+#  if HAVE_SYS_DIR_H
+#    include <sys/dir.h>
+#  endif
+#  if HAVE_NDIR_H
+#    include <ndir.h>
+#  endif
+#endif
+
+#ifdef HAVE_FCNTL_H
+#  include <fcntl.h>
+#endif
+
+#ifdef HAVE_GRP_H
+#  include <grp.h>
+#endif
+
+#if defined(USE_DB_H)
+#  include <db.h>
+#else
+#if defined(USE_DBM_H)
+#  include <dbm.h>
+#else
+#if defined(USE_GDBM_H)
+#  include <gdbm.h>
+#else
+#if defined(USE_NDBM_H)
+#  include <ndbm.h>
+#endif
+#endif
+#endif
+#endif
+
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+
+#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
+
+#ifdef HAVE_LIBC_H
+#  include <libc.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#  include <string.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#ifdef HAVE_SYSLOG_H
+#  include <syslog.h>
+#endif
+
+#ifdef HAVE_SYS_FILE_H
+#  include <sys/file.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+#  include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+#endif
+
+#if defined(HAVE_SYS_IPC_H) && defined(HAVE_SYS_SHM_H)
+#  include <sys/ipc.h>
+#  include <sys/shm.h>
+#else
+#  ifdef HAVE_SYS_MMAN_H
+#    include <sys/mman.h>
+#  endif
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#  include <sys/select.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#  include <sys/stat.h>
+#endif
+
+#ifdef HAVE_WAIT_H
+#  include <wait.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#  include <sys/wait.h>
+#endif
+
+#ifdef WAIT_USES_UNION
+  typedef union wait amwait_t;
+# ifndef WEXITSTATUS
+#  define WEXITSTATUS(stat_val) (((amwait_t*)&(stat_val))->w_retcode)
+# endif
+# ifndef WTERMSIG
+#  define WTERMSIG(stat_val) (((amwait_t*)&(stat_val))->w_termsig)
+# endif
+# ifndef WIFEXITED
+#  define WIFEXITED(stat_val) (WTERMSIG(stat_val) == 0)
+# endif
+#else
+  typedef int amwait_t;
+# ifndef WEXITSTATUS
+#  define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
+# endif
+# ifndef WTERMSIG
+#  define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
+# endif
+# ifndef WIFEXITED
+#  define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
+# endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+
+/*
+ * At present, the kerberos routines require atexit(), or equivilent.  If 
+ * you're not using kerberos, you don't need it at all.  If you just null
+ * out the definition, you'll end up with ticket files hanging around in
+ * /tmp.
+ */
+#if defined(KRB4_SECURITY)
+#   if !defined(HAVE_ATEXIT) 
+#      if defined(HAVE_ON_EXIT)
+#          define atexit(func) on_exit(func, 0)
+#      else
+#         define atexit(func) (you must to resolve lack of atexit in amanda.h)
+#      endif
+#   endif
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <pwd.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <sys/resource.h>
+#include <sys/socket.h>
+#if !defined(CONFIGURE_TEST)
+#  include "amanda-int.h"
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#ifdef KRB4_SECURITY
+#  include <des.h>
+#  include <krb.h>
+#endif
+
+/*
+ * The dbmalloc package comes from:
+ *
+ *  http://www.clark.net/pub/dickey/dbmalloc/dbmalloc.tar.gz
+ *
+ * or
+ *
+ *  ftp://gatekeeper.dec.com/pub/usenet/comp.sources.misc/volume32/dbmalloc/
+ *
+ * The following functions are sprinkled through the code, but are
+ * disabled unless USE_DBMALLOC is defined:
+ *
+ *  malloc_enter(char *) -- stack trace for malloc reports
+ *  malloc_leave(char *) -- stack trace for malloc reports
+ *  malloc_mark(void *) -- mark an area as never to be free-d
+ *  malloc_chain_check(void) -- check the malloc area now
+ *  malloc_dump(int fd) -- report the malloc contents to a file descriptor
+ *  malloc_list(int fd, ulong a, ulong b) -- report memory activated since
+ *     history stamp a that is still active as of stamp b (leak check)
+ *  malloc_inuse(ulong *h) -- create history stamp h and return the amount
+ *     of memory currently in use.
+ */
+
+#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_inuse(hist)              (*(hist) = 0, 0)
+#define        dbmalloc_caller_loc(x,y)        (x)
+#endif
+
+#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC)
+/* quick'n'dirty hack for NextStep31 */
+#  define sa_flags sv_flags
+#  define sa_handler sv_handler
+#  define sa_mask sv_mask
+#  define sigaction sigvec
+#  define sigemptyset(mask) /* no way to clear pending signals */
+#endif
+
+/*
+ * Most Unixen declare errno in <errno.h>, some don't.  Some multithreaded
+ * systems have errno as a per-thread macro.  So, we have to be careful.
+ */
+#ifndef errno
+extern int errno;
+#endif
+
+
+/*
+ * 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)))
+#endif
+
+
+/*
+ * Define MAX_HOSTNAME_LENGTH as the size of arrays to hold hostname's.
+ */
+#undef  MAX_HOSTNAME_LENGTH
+#define MAX_HOSTNAME_LENGTH 1025
+
+/*
+ * If void is broken, substitute char.
+ */
+#ifdef BROKEN_VOID
+#  define void char
+#endif
+
+/*
+ * define prototype macro so that prototypes can be declared in both ANSI
+ * and classic C environments.
+ */
+#if STDC_HEADERS
+#  define P(parms)     parms
+#  define stringize(x) #x
+#else
+#  define P(parms)     ()
+#  define stringize(x) "x"
+#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 ...
+ * it may work on earlier stuff, but why chance it.
+ */
+#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7
+#define __attribute__(__x)
+#endif
+
+/*
+ * assertions, but call error() instead of abort 
+ */
+#ifndef ASSERTIONS
+
+#define assert(exp) ((void)0)
+
+#else  /* ASSERTIONS */
+
+#define assert(exp) {if(!(exp)) error("assert: %s false, file %s, line %d", \
+                                  stringize(exp), __FILE__, __LINE__);}
+
+#endif /* ASSERTIONS */
+
+/*
+ * print debug output, else compile to nothing.
+ */
+
+#ifdef DEBUG_CODE                                                      /* { */
+#   define dbopen()    debug_open()
+#   define dbclose()   debug_close()
+#   define dbprintf(p) (debug? (debug_printf p, 0) : 0)
+#   define dbfd()      debug_fd()
+#   define dbfp()      debug_fp()
+#   define dbfn()      debug_fn()
+
+extern void debug_open P((void));
+extern void debug_close P((void));
+extern void debug_printf P((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 *));
+#else                                                                  /* }{ */
+#   define dbopen()
+#   define dbclose()
+#   define dbprintf(p)
+#   define dbfd()      (-1)
+#   define dbfp()      NULL
+#   define dbfn()      NULL
+#   define set_debug_prefix_pid(x)
+#   define debug_prefix(x) get_pname()
+#   define debug_prefix_time(x) get_pname()
+#endif                                                                 /* } */
+
+/* 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)
+
+/* Global constants.  */
+#ifndef AMANDA_SERVICE_NAME
+#define AMANDA_SERVICE_NAME "amanda"
+#endif
+#ifndef KAMANDA_SERVICE_NAME
+#define KAMANDA_SERVICE_NAME "kamanda"
+#endif
+#ifndef SERVICE_SUFFIX
+#define SERVICE_SUFFIX ""
+#endif
+#ifndef AMANDA_SERVICE_DEFAULT
+#define AMANDA_SERVICE_DEFAULT 10080
+#endif
+#ifndef KAMANDA_SERVICE_DEFAULT
+#define KAMANDA_SERVICE_DEFAULT        10081
+#endif
+
+#define am_round(v,u)  ((((v) + (u) - 1) / (u)) * (u))
+#define am_floor(v,u)  (((v) / (u)) * (u))
+
+/* Holding disk block size.  Do not even think about changing this!  :-) */
+#define DISK_BLOCK_KB          32
+#define DISK_BLOCK_BYTES       (DISK_BLOCK_KB * 1024)
+
+/* Maximum size of a tape block */
+/* MAX_TAPE_BLOCK_KB is defined in config.h */
+/* by configure --with-maxtapeblocksize     */
+#define MAX_TAPE_BLOCK_BYTES (MAX_TAPE_BLOCK_KB*1024)
+
+/* Define miscellaneous amanda functions.  */
+#define ERR_INTERACTIVE        1
+#define ERR_SYSLOG     2
+#define ERR_AMANDALOG  4
+
+/* For static buffer manager [alloc.c:sbuf_man()] */
+#define SBUF_MAGIC 42
+#define SBUF_DEF(name, len) static SBUF2_DEF(len) name = {SBUF_MAGIC, len, -1}
+#define SBUF2_DEF(len)                 \
+    struct {                   \
+       int magic;              \
+       int max, cur;           \
+       void *bufp[len];        \
+    }
+
+extern void   set_logerror P((void (*f)(char *)));
+extern void   set_pname P((char *pname));
+extern char  *get_pname P((void));
+extern int    erroutput_type;
+extern void   error     P((char *format, ...))
+    __attribute__ ((format (printf, 1, 2)));
+extern void   errordump P((char *format, ...))
+    __attribute__ ((format (printf, 1, 2)));
+extern int    onerror         P((void (*errf)(void)));
+
+extern void  *debug_alloc           P((char *c, int l, size_t size));
+extern void  *debug_newalloc        P((char *c, int l, void *old, size_t size));
+extern char  *debug_stralloc        P((char *c, int l, const char *str));
+extern char  *debug_newstralloc     P((char *c, int l, char *oldstr, const char *newstr));
+extern char  *debug_caller_loc      P((char *file, int line));
+
+extern int   debug_alloc_push      P((char *file, int line));
+extern void  debug_alloc_pop       P((void));
+
+#define        alloc(s)                debug_alloc(__FILE__, __LINE__, (s))
+#define        newalloc(p,s)           debug_newalloc(__FILE__, __LINE__, (p), (s))
+#define        stralloc(s)             debug_stralloc(__FILE__, __LINE__, (s))
+#define        newstralloc(p,s)        debug_newstralloc(__FILE__, __LINE__, (p), (s))
+
+/*
+ * Voodoo time.  We want to be able to mark these calls with the source
+ * line, but CPP does not handle variable argument lists so we cannot
+ * do what we did above (e.g. for alloc()).
+ *
+ * What we do is call a function to save the file and line number
+ * and have it return "false".  That triggers the "?" operator to
+ * the right side of the ":" which is a call to the debug version of
+ * vstralloc/newvstralloc but without parameters.  The compiler gets
+ * those from the next input tokens:
+ *
+ *  xx = vstralloc(a,b,NULL);
+ *
+ * becomes:
+ *
+ *  xx = debug_alloc_push(__FILE__,__LINE__)?0:debug_vstralloc(a,b,NULL);
+ *
+ * This works as long as vstralloc/newvstralloc are not part of anything
+ * very complicated.  Assignment is fine, as is an argument to another
+ * function (but you should not do that because it creates a memory leak).
+ * This will not work in arithmetic or comparison, but it is unlikely
+ * they are used like that.
+ *
+ *  xx = vstralloc(a,b,NULL);                  OK
+ *  return vstralloc(j,k,NULL);                        OK
+ *  sub(a, vstralloc(g,h,NULL), z);            OK, but a leak
+ *  if(vstralloc(s,t,NULL) == NULL) { ...      NO, but unneeded
+ *  xx = vstralloc(x,y,NULL) + 13;             NO, but why do it?
+ */
+
+#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, ...));
+
+#define        stralloc2(s1,s2)      vstralloc((s1),(s2),NULL)
+#define        newstralloc2(p,s1,s2) newvstralloc((p),(s1),(s2),NULL)
+
+extern char  *debug_agets     P((char *c, int l, FILE *file));
+extern char  *debug_areads    P((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((char *file,
+                                 int line,
+                                 void **table,
+                                 int *current,
+                                 size_t elsize,
+                                 int count,
+                                 int bump,
+                                 void (*init_func)(void *)));
+#define amtable_alloc(t,c,s,n,b,f) debug_amtable_alloc(__FILE__,       \
+                                                      __LINE__,        \
+                                                      (t),             \
+                                                      (c),             \
+                                                      (s),             \
+                                                      (n),             \
+                                                      (b),             \
+                                                      (f))
+extern void amtable_free      P((void **table, int *current));
+
+extern void  *sbuf_man        P((void *bufs, void *ptr));
+extern uid_t  client_uid;
+extern gid_t  client_gid;
+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_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 time_t unctime         P((char *timestr));
+extern ssize_t  areads_dataready  P((int fd));
+extern void     areads_relbuf     P((int fd));
+
+/*
+ * amfree(ptr) -- if allocated, release space and set ptr to NULL.
+ *
+ * In general, this should be called instead of just free(), unless
+ * the very next source line sets the pointer to a new value.
+ */
+
+#define        amfree(ptr) do {                                                \
+    if(ptr) {                                                          \
+       int e__errno = errno;                                           \
+       free(ptr);                                                      \
+       (ptr) = NULL;                                                   \
+       errno = e__errno;                                               \
+    }                                                                  \
+} while(0)
+
+#define strappend(s1,s2) do {                                          \
+    char *t_t_t = (s1) ? stralloc2((s1),(s2)) : stralloc((s2));                \
+    amfree((s1));                                                      \
+    (s1) = t_t_t;                                                      \
+} while(0)
+
+/*
+ * "Safe" close macros.  Close the object then set it to a value that
+ * will cause an error if referenced.
+ *
+ * aclose(fd) -- close a file descriptor and set it to -1.
+ * afclose(f) -- close a stdio file and set it to NULL.
+ * apclose(p) -- close a stdio pipe file and set it to NULL.
+ *
+ * Note: be careful not to do the following:
+ *
+ *  for(fd = low; fd < high; fd++) {
+ *      aclose(fd);
+ *  }
+ *
+ * Since aclose() sets the argument to -1, this will loop forever.
+ * Just copy fd to a temp variable and use that with aclose().
+ *
+ * Aclose() interacts with areads() to inform it to release any buffer
+ * it has outstanding on the file descriptor.
+ */
+
+#define aclose(fd) do {                                                        \
+    if((fd) >= 0) {                                                    \
+       close(fd);                                                      \
+       areads_relbuf(fd);                                              \
+    }                                                                  \
+    (fd) = -1;                                                         \
+} while(0)
+
+#define afclose(f) do {                                                        \
+    if((f) != NULL) {                                                  \
+       fclose(f);                                                      \
+    }                                                                  \
+    (f) = NULL;                                                                \
+} while(0)
+
+#define apclose(p) do {                                                        \
+    if((p) != NULL) {                                                  \
+       pclose(p);                                                      \
+    }                                                                  \
+    (p) = NULL;                                                                \
+} while(0)
+
+/*
+ * Return the number of elements in an array.
+ */
+#define am_countof(a)        (sizeof(a) / sizeof((a)[0]))
+
+/*
+ * min/max.  Don't do something like
+ *
+ *    x = min(y++, z);
+ *
+ * because the increment will be duplicated.
+ */
+#undef min
+#undef max
+#define min(a, b)       ((a) < (b) ? (a) : (b))
+#define max(a, b)       ((a) > (b) ? (a) : (b))
+
+/*
+ * Utility string macros.  All assume a variable holds the current
+ * character and the string pointer points to the next character to
+ * be processed.  Typical setup is:
+ *
+ *  s = buffer;
+ *  ch = *s++;
+ *  skip_whitespace(s, ch);
+ *  ...
+ *
+ * If you advance the pointer "by hand" to skip over something, do
+ * it like this:
+ *
+ *  s += some_amount;
+ *  ch = s[-1];
+ *
+ * Note that ch has the character at the end of the just skipped field.
+ * It is often useful to terminate a string, make a copy, then restore
+ * the input like this:
+ *
+ *  skip_whitespace(s, ch);
+ *  fp = s-1;                  ## save the start
+ *  skip_nonwhitespace(s, ch); ## find the end
+ *  p[-1] = '\0';              ## temporary terminate
+ *  field = stralloc(fp);      ## make a copy
+ *  p[-1] = ch;                        ## restore the input
+ *
+ * The scanning macros are:
+ *
+ *  skip_whitespace (ptr, var)
+ *    -- skip whitespace, but stops at a newline
+ *  skip_non_whitespace (ptr, var)
+ *    -- skip non whitespace
+ *  skip_non_whitespace_cs (ptr, var)
+ *    -- skip non whitespace, stop at comment
+ *  skip_integer (ptr, var)
+ *    -- skip an integer field
+ *  skip_line (ptr, var)
+ *    -- skip just past the next newline
+ *
+ * where:
+ *
+ *  ptr -- string pointer
+ *  var -- current character
+ *
+ * These macros copy a non-whitespace field to a new buffer, and should
+ * only be used if dynamic allocation is impossible (fixed size buffers
+ * are asking for trouble):
+ *
+ *  copy_string (ptr, var, field, len, fldptr)
+ *    -- copy a non-whitespace field
+ *  copy_string_cs (ptr, var, field, len, fldptr)
+ *    -- copy a non-whitespace field, stop at comment
+ *
+ * where:
+ *
+ *  ptr -- string pointer
+ *  var -- current character
+ *  field -- area to copy to
+ *  len -- length of area (needs room for null byte)
+ *  fldptr -- work pointer used in move
+ *           if NULL on exit, the field was too small for the input
+ */
+
+#define        STR_SIZE        1024            /* a generic string buffer size */
+#define        NUM_STR_SIZE    32              /* a generic number buffer size */
+
+#define        skip_whitespace(ptr,c) do {                                     \
+    while((c) != '\n' && isspace(c)) (c) = *(ptr)++;                   \
+} while(0)
+
+#define        skip_non_whitespace(ptr,c) do {                                 \
+    while((c) != '\0' && !isspace(c)) (c) = *(ptr)++;                  \
+} while(0)
+
+#define        skip_non_whitespace_cs(ptr,c) do {                              \
+    while((c) != '\0' && (c) != '#' && !isspace(c)) (c) = *(ptr)++;    \
+} while(0)
+
+#define        skip_non_integer(ptr,c) do {                                    \
+    while((c) != '\0' && !isdigit(c)) (c) = *(ptr)++;                  \
+} while(0)
+
+#define        skip_integer(ptr,c) do {                                        \
+    if((c) == '+' || (c) == '-') (c) = *(ptr)++;                       \
+    while(isdigit(c)) (c) = *(ptr)++;                                  \
+} while(0)
+
+#define        skip_line(ptr,c) do {                                           \
+    while((c) && (c) != '\n') (c) = *(ptr)++;                          \
+    if(c) (c) = *(ptr)++;                                              \
+} while(0)
+
+#define        copy_string(ptr,c,f,l,fp) do {                                  \
+    (fp) = (f);                                                                \
+    while((c) != '\0' && !isspace(c)) {                                        \
+       if((fp) >= (f) + (l) - 1) {                                     \
+           *(fp) = '\0';                                               \
+           (fp) = NULL;                                                \
+           break;                                                      \
+       }                                                               \
+       *(fp)++ = (c);                                                  \
+       (c) = *(ptr)++;                                                 \
+    }                                                                  \
+    if(fp) *fp = '\0';                                                 \
+} while(0)
+
+#define        copy_string_cs(ptr,c,f,l,fp) do {                               \
+    (fp) = (f);                                                                \
+    while((c) != '\0' && (c) != '#' && !isspace(c)) {                  \
+       if((fp) >= (f) + (l) - 1) {                                     \
+           *(fp) = '\0';                                               \
+           (fp) = NULL;                                                \
+           break;                                                      \
+       }                                                               \
+       *(fp)++ = (c);                                                  \
+       (c) = *(ptr)++;                                                 \
+    }                                                                  \
+    if(fp) *fp = '\0';                                                 \
+} while(0)
+
+#define is_dot_or_dotdot(s)                                            \
+    ((s)[0] == '.'                                                     \
+     && ((s)[1] == '\0'                                                        \
+        || ((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));
+
+/* 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));
+
+extern int debug;
+extern char *version_info[];
+
+/* from security.c */
+extern int security_ok P((struct sockaddr_in *addr,
+                         char *str, uint32_t cksum, char **errstr));
+extern char *get_bsd_security P((void));
+
+/*
+ * Handle functions which are not always declared on all systems.  This
+ * stops gcc -Wall and lint from complaining.
+ */
+
+/* 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));
+#endif
+
+#ifndef HAVE_ATOF_DECL
+extern double atof P((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));
+# endif
+#endif
+
+#ifndef HAVE_BIND_DECL
+extern int bind P((int s, const struct sockaddr *name, int 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));
+# endif
+#endif
+
+#ifndef HAVE_CLOSELOG_DECL
+extern void closelog P((void));
+#endif
+
+#ifndef HAVE_CONNECT_DECL
+extern int connect P((int s, struct sockaddr *name, int namelen));
+#endif
+
+#if !defined(TEXTDB) && !defined(HAVE_DBM_OPEN_DECL)
+#undef   DBM_INSERT
+#define  DBM_INSERT  0
+
+#undef   DBM_REPLACE
+#define  DBM_REPLACE 1
+
+    typedef struct {
+       int dummy[10];
+    } DBM;
+
+#ifndef HAVE_STRUCT_DATUM
+    typedef struct {
+       char    *dptr;
+       int     dsize;
+    } 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));
+#endif
+
+#ifndef HAVE_FCLOSE_DECL
+extern int fclose P((FILE *stream));
+#endif
+
+#ifndef HAVE_FFLUSH_DECL
+extern int fflush P((FILE *stream));
+#endif
+
+#ifndef HAVE_FPRINTF_DECL
+extern int fprintf P((FILE *stream, const char *format, ...));
+#endif
+
+#ifndef HAVE_FPUTC_DECL
+extern int fputc P((int c, FILE *stream));
+#endif
+
+#ifndef HAVE_FPUTS_DECL
+extern int fputs P((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));
+#endif
+
+#ifndef HAVE_FSEEK_DECL
+extern int fseek P((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));
+#endif
+
+#ifndef HAVE_GETHOSTNAME_DECL
+extern int gethostname P((char *name, int namelen));
+#endif
+
+#ifndef HAVE_GETOPT_DECL
+extern char *optarg;
+extern int getopt P((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));
+#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));
+#endif
+
+#ifndef HAVE_GETSOCKOPT_DECL
+extern int getsockopt P((int s, int level, int optname, char *optval,
+                        int *optlen));
+#endif
+
+#ifndef HAVE_GETTIMEOFDAY_DECL
+# ifdef HAVE_TWO_ARG_GETTIMEOFDAY
+extern int gettimeofday P((struct timeval *tp, struct timezone *tzp));
+# else
+extern int gettimeofday P((struct timeval *tp));
+# endif
+#endif
+
+#ifndef HAVE_INITGROUPS
+# define initgroups(name,basegid) 0
+#else
+# ifndef HAVE_INITGROUPS_DECL
+/* modification by BIS@BBN 5/20/2003:
+ * In some Unix systems, basegid is defined as a gid_t; in others
+ * it is defined as an int.  On Mac OS X, there is a "pre-compiled"
+ * unistd.h which causes the gcc -E command in the ICE_CHECK_DECL
+ * autoconf macro to not succeed.  Thus, on Mac OS X, configure thinks
+ * we don't have this declaration when we actually do.  Since Mac OS X
+ * defines basegid as an int, this declaration causes a compilation
+ * failure.  The path of least resistance for fixing this problem
+ * is to just change the basegid declaration from gid_t to int, since
+ * other (but not all) UNIX flavors also defined basegid as an int.
+extern int initgroups P((const char *name, gid_t basegid));
+ */
+extern int initgroups P((const char *name, int basegid));
+# endif
+#endif
+
+#ifndef HAVE_IOCTL_DECL
+extern int ioctl P((int fildes, int request, ...));
+#endif
+
+#ifndef HAVE_LISTEN_DECL
+extern int listen P((int s, int backlog));
+#endif
+
+#ifndef HAVE_LSTAT_DECL
+extern int lstat P((const char *path, struct stat *buf));
+#endif
+
+#ifndef HAVE_MALLOC_DECL
+extern void *malloc P((size_t size));
+#endif
+
+#ifndef HAVE_MEMMOVE_DECL
+#ifdef HAVE_MEMMOVE
+extern void *memmove P((void *to, const void *from, size_t n));
+#else
+extern char *memmove P((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));
+#endif
+
+#ifndef HAVE_MKTEMP_DECL
+extern char *mktemp P((char *template));
+#endif
+
+#ifndef HAVE_MKTIME_DECL
+extern time_t mktime P((struct tm *timeptr));
+#endif
+
+#ifndef HAVE_OPENLOG_DECL
+#ifdef LOG_AUTH
+extern void openlog P((const char *ident, int logopt, int facility));
+#else
+extern void openlog P((const char *ident, int logopt));
+#endif
+#endif
+
+#ifndef HAVE_PCLOSE_DECL
+extern int pclose P((FILE *stream));
+#endif
+
+#ifndef HAVE_PERROR_DECL
+extern void perror P((const char *s));
+#endif
+
+#ifndef HAVE_PRINTF_DECL
+extern int printf P((const char *format, ...));
+#endif
+
+#ifndef HAVE_PUTS_DECL
+extern int puts P((const char *s));
+#endif
+
+#ifndef HAVE_REALLOC_DECL
+extern void *realloc P((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));
+#endif
+
+#ifndef HAVE_REMOVE_DECL
+extern int remove P((const char *path));
+#endif
+
+#ifndef HAVE_RENAME_DECL
+extern int rename P((const char *old, const char *new));
+#endif
+
+#ifndef HAVE_REWIND_DECL
+extern void rewind P((FILE *stream));
+#endif
+
+#ifndef HAVE_RUSEROK_DECL
+extern int ruserok P((const char *rhost, int suser,
+                     const char *ruser, const char *luser));
+#endif
+
+#ifndef HAVE_SELECT_DECL
+extern int select P((int nfds,
+                    SELECT_ARG_TYPE *readfds,
+                    SELECT_ARG_TYPE *writefds,
+                    SELECT_ARG_TYPE *exceptfds,
+                    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));
+#endif
+
+#ifdef HAVE_SETRESGID
+#define        setegid(x)      setresgid(-1,(x),-1)
+#ifndef HAVE_SETRESGID_DECL
+extern int setresgid P((gid_t rgid, gid_t egid, gid_t sgid));
+#endif
+#else
+#ifndef HAVE_SETEGID_DECL
+extern int setegid P((gid_t egid));
+#endif
+#endif
+
+#ifdef HAVE_SETRESUID
+#define        seteuid(x)      setresuid(-1,(x),-1)
+#ifndef HAVE_SETRESUID_DECL
+extern int setresuid P((uid_t ruid, uid_t euid, uid_t suid));
+#endif
+#else
+#ifndef HAVE_SETEUID_DECL
+extern int seteuid P((uid_t euid));
+#endif
+#endif
+
+#ifndef HAVE_SETPGID_DECL
+#ifdef HAVE_SETPGID
+extern int setpgid P((int pid, int pgid));
+#endif
+#endif
+
+#ifndef HAVE_SETPGRP_DECL
+#ifdef SETPGRP_VOID
+extern pid_t setpgrp P((void));
+#else
+extern pid_t setpgrp P((int pgrp, int pid));
+#endif
+#endif
+
+#ifndef HAVE_SETSOCKOPT_DECL
+extern int setsockopt P((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));
+#endif
+
+#ifndef HAVE_SHMCTL_DECL
+extern int shmctl P((int shmid, int cmd, struct shmid_ds *buf));
+#endif
+
+#ifndef HAVE_SHMDT_DECL
+extern int shmdt P((SHM_ARG_TYPE *shaddr));
+#endif
+
+#ifndef HAVE_SHMGET_DECL
+extern int shmget P((key_t key, size_t size, int shmflg));
+#endif
+#endif
+
+#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF)
+#define ap_snprintf    snprintf
+#define ap_vsnprintf   vsnprintf
+#endif
+#ifndef HAVE_SNPRINTF_DECL
+#include "arglist.h"
+int ap_snprintf  P((char *buf, size_t len, const char *format,...))
+                   __attribute__((format(printf,3,4)));
+#endif
+#ifndef HAVE_VSNPRINTF_DECL
+#include "arglist.h"
+int ap_vsnprintf P((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));
+#endif
+
+#ifndef HAVE_SOCKETPAIR_DECL
+extern int socketpair P((int domain, int type, int protocol, int sv[2]));
+#endif
+
+#ifndef HAVE_SSCANF_DECL
+extern int sscanf P((const char *s, const char *format, ...));
+#endif
+
+#ifndef HAVE_STRCASECMP_DECL
+extern int strcasecmp P((const char *s1, const char *s2));
+#endif
+
+#ifndef HAVE_STRERROR_DECL
+extern char *strerror P((int errnum));
+#endif
+
+#ifndef HAVE_STRFTIME_DECL
+extern size_t strftime P((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));
+#endif
+
+#ifndef HAVE_SYSLOG_DECL
+extern void syslog P((int priority, const char *logstring, ...))
+    __attribute__ ((format (printf, 2, 3)));
+#endif
+
+#ifndef HAVE_SYSTEM_DECL
+extern int system P((const char *string));
+#endif
+
+#ifndef HAVE_TIME_DECL
+extern time_t time P((time_t *tloc));
+#endif
+
+#ifndef HAVE_TOLOWER_DECL
+extern int tolower P((int c));
+#endif
+
+#ifndef HAVE_TOUPPER_DECL
+extern int toupper P((int c));
+#endif
+
+#ifndef HAVE_UNGETC_DECL
+extern int ungetc P((int c, FILE *stream));
+#endif
+
+#ifndef HAVE_VFPRINTF_DECL
+#include "arglist.h"
+extern int vfprintf P((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));
+#endif
+
+#if !defined(S_ISCHR) && defined(_S_IFCHR) && defined(_S_IFMT)
+#define S_ISCHR(mode) (((mode) & _S_IFMT) == _S_IFCHR)
+#endif
+
+#if !defined(S_ISREG) && defined(_S_IFREG) && defined(_S_IFMT)
+#define S_ISREG(mode) (((mode) & _S_IFMT) == _S_IFREG)
+#endif
+
+#ifndef HAVE_WAITPID
+#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));
+#endif
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+/* S_ISDIR is not defined on Nextstep */
+#ifndef S_ISDIR
+#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
+#endif
+#endif
+
+#endif /* !AMANDA_H */
diff --git a/common-src/amfeatures.c b/common-src/amfeatures.c
new file mode 100644 (file)
index 0000000..7305793
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * 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: amfeatures.c,v 1.1.2.9 2003/01/01 23:28:52 martinea Exp $
+ *
+ * Feature test related code.
+ */
+
+#include <amanda.h>
+#include <amfeatures.h>
+
+/*
+ *=====================================================================
+ * Initialize the base feature set for this version of Amanda.
+ *
+ * am_feature_t *am_init_feature_set()
+ *
+ * entry:      none
+ * exit:       dynamically allocated feature set structure
+ *=====================================================================
+ */
+
+am_feature_t *
+am_init_feature_set()
+{
+    am_feature_t               *f = NULL;
+
+    if ((f = am_allocate_feature_set()) != NULL) {
+       /*
+        * Whenever a new feature is added, a new line usually needs
+        * to be added here to show that we support it.
+        */
+       am_add_feature(f, have_feature_support);
+       am_add_feature(f, fe_options_auth);
+
+       am_add_feature(f, fe_selfcheck_req);
+       am_add_feature(f, fe_selfcheck_req_device);
+       am_add_feature(f, fe_selfcheck_rep);
+       am_add_feature(f, fe_sendsize_req_no_options);
+       am_add_feature(f, fe_sendsize_req_options);
+       am_add_feature(f, fe_sendsize_req_device);
+       am_add_feature(f, fe_sendsize_rep);
+       am_add_feature(f, fe_sendbackup_req);
+       am_add_feature(f, fe_sendbackup_req_device);
+       am_add_feature(f, fe_sendbackup_rep);
+       am_add_feature(f, fe_noop_req);
+       am_add_feature(f, fe_noop_rep);
+
+       am_add_feature(f, fe_program_dump);
+       am_add_feature(f, fe_program_gnutar);
+
+       am_add_feature(f, fe_options_compress_fast);
+       am_add_feature(f, fe_options_compress_best);
+       am_add_feature(f, fe_options_srvcomp_fast);
+       am_add_feature(f, fe_options_srvcomp_best);
+       am_add_feature(f, fe_options_no_record);
+       am_add_feature(f, fe_options_bsd_auth);
+       am_add_feature(f, fe_options_index);
+       am_add_feature(f, fe_options_exclude_file);
+       am_add_feature(f, fe_options_exclude_list);
+       am_add_feature(f, fe_options_multiple_exclude);
+       am_add_feature(f, fe_options_optional_exclude);
+       am_add_feature(f, fe_options_include_file);
+       am_add_feature(f, fe_options_include_list);
+       am_add_feature(f, fe_options_multiple_include);
+       am_add_feature(f, fe_options_optional_include);
+       am_add_feature(f, fe_options_krb4_auth);
+       am_add_feature(f, fe_options_kencrypt);
+
+       am_add_feature(f, fe_req_options_maxdumps);
+       am_add_feature(f, fe_req_options_hostname);
+       am_add_feature(f, fe_req_options_features);
+
+       am_add_feature(f, fe_rep_options_features);
+
+       am_add_feature(f, fe_amindexd_fileno_in_OLSD);
+       am_add_feature(f, fe_amindexd_fileno_in_ORLD);
+       am_add_feature(f, fe_amidxtaped_fsf);
+       am_add_feature(f, fe_amidxtaped_label);
+       am_add_feature(f, fe_amidxtaped_device);
+       am_add_feature(f, fe_amidxtaped_host);
+       am_add_feature(f, fe_amidxtaped_disk);
+       am_add_feature(f, fe_amidxtaped_datestamp);
+       am_add_feature(f, fe_amidxtaped_header);
+       am_add_feature(f, fe_amidxtaped_nargs);
+       am_add_feature(f, fe_amidxtaped_config);
+    }
+    return f;
+}
+
+/*
+ *=====================================================================
+ * Set a default feature set for client that doesn't have noop service.
+ * This is all the features available in 2.4.2p2.
+ *
+ * entry:      none
+ * exit: dynamically allocated feature set
+ *=====================================================================
+ */
+am_feature_t *
+am_set_default_feature_set(void)
+{
+    am_feature_t               *f;
+
+    if ((f = am_allocate_feature_set()) != NULL) {
+
+       am_add_feature(f, fe_selfcheck_req);
+       am_add_feature(f, fe_selfcheck_rep);
+       am_add_feature(f, fe_sendsize_req_no_options);
+       am_add_feature(f, fe_sendsize_rep);
+       am_add_feature(f, fe_sendbackup_req);
+       am_add_feature(f, fe_sendbackup_rep);
+
+       am_add_feature(f, fe_program_dump);
+       am_add_feature(f, fe_program_gnutar);
+
+       am_add_feature(f, fe_options_compress_fast);
+       am_add_feature(f, fe_options_compress_best);
+       am_add_feature(f, fe_options_srvcomp_fast);
+       am_add_feature(f, fe_options_srvcomp_best);
+       am_add_feature(f, fe_options_no_record);
+       am_add_feature(f, fe_options_bsd_auth);
+       am_add_feature(f, fe_options_index);
+       am_add_feature(f, fe_options_exclude_file);
+       am_add_feature(f, fe_options_exclude_list);
+       am_add_feature(f, fe_options_krb4_auth);
+       am_add_feature(f, fe_options_kencrypt);
+
+       am_add_feature(f, fe_req_options_maxdumps);
+       am_add_feature(f, fe_req_options_hostname);
+       am_add_feature(f, fe_req_options_features);
+
+       am_add_feature(f, fe_rep_options_sendbackup_options);
+    }
+    return f;
+}
+
+/*
+ *=====================================================================
+ * Allocate space for a feature set.
+ *
+ * am_feature_t *am_allocate_feature_set()
+ *
+ * entry:      none
+ * exit:       dynamically allocated feature set structure
+ *=====================================================================
+ */
+
+am_feature_t *
+am_allocate_feature_set()
+{
+    size_t                     nbytes;
+    am_feature_t               *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);
+    memset(result->bytes, 0, nbytes);
+    return result;
+}
+
+/*
+ *=====================================================================
+ * Release space allocated to a feature set.
+ *
+ * void am_release_feature_set(am_feature_t *f)
+ *
+ * entry:      f = feature set to release
+ * exit:       none
+ *=====================================================================
+ */
+
+void
+am_release_feature_set(f)
+    am_feature_t               *f;
+{
+    if (f != NULL) {
+       amfree(f->bytes);
+       f->size = 0;
+    }
+    amfree(f);
+}
+
+/*
+ *=====================================================================
+ * Add a feature to a feature set.
+ *
+ * int am_add_feature(am_feature_t *f, am_feature_e n)
+ *
+ * entry:      f = feature set to add to
+ *             n = feature to add
+ * exit:       non-zero if feature added, else zero (e.g. if the feature
+ *             is beyond what is currently supported)
+ *=====================================================================
+ */
+
+int
+am_add_feature(f, n)
+    am_feature_t               *f;
+    am_feature_e               n;
+{
+    size_t                     byte;
+    int                                bit;
+    int                                result = 0;
+
+    if (f != NULL && (int)n >= 0) {
+       byte = ((size_t)n) >> 3;
+       if (byte < f->size) {
+           bit = ((int)n) & 0x7;
+           f->bytes[byte] |= (1 << bit);
+           result = 1;
+       }
+    }
+    return result;
+}
+
+/*
+ *=====================================================================
+ * Remove a feature from a feature set.
+ *
+ * int am_remove_feature(am_feature_t *f, am_feature_e n)
+ *
+ * entry:      f = feature set to remove from
+ *             n = feature to remove
+ * exit:       non-zero if feature removed, else zero (e.g. if the feature
+ *             is beyond what is currently supported)
+ *=====================================================================
+ */
+
+int
+am_remove_feature(f, n)
+    am_feature_t               *f;
+    am_feature_e               n;
+{
+    size_t                     byte;
+    int                                bit;
+    int                                result = 0;
+
+    if (f != NULL && (int)n >= 0) {
+       byte = ((size_t)n) >> 3;
+       if (byte < f->size) {
+           bit = ((int)n) & 0x7;
+           f->bytes[byte] &= ~(1 << bit);
+           result = 1;
+       }
+    }
+    return result;
+}
+
+/*
+ *=====================================================================
+ * Return true if a given feature is available.
+ *
+ * int am_has_feature(am_feature_t *f, am_feature_e n)
+ *
+ * entry:      f = feature set to test
+ *             n = feature to test
+ * exit:       non-zero if feature is enabled
+ *=====================================================================
+ */
+
+int
+am_has_feature(f, n)
+    am_feature_t               *f;
+    am_feature_e               n;
+{
+    size_t                     byte;
+    int                                bit;
+    int                                result = 0;
+
+    if (f != NULL && (int)n >= 0) {
+       byte = ((size_t)n) >> 3;
+       if (byte < f->size) {
+           bit = ((int)n) & 0x7;
+           result = ((f->bytes[byte] & (1 << bit)) != 0);
+       }
+    }
+    return result;
+}
+
+/*
+ *=====================================================================
+ * Convert a feature set to string.
+ *
+ * char *am_feature_to_string(am_feature_t *f)
+ *
+ * entry:      f = feature set to convet
+ * exit:       dynamically allocated string
+ *=====================================================================
+ */
+
+char *
+am_feature_to_string(f)
+    am_feature_t               *f;
+{
+    char                       *result;
+    size_t                     i;
+
+    if (f == NULL) {
+       result = stralloc("UNKNOWNFEATURE");
+    } else {
+       result = alloc((f->size * 2) + 1);
+       for (i = 0; i < f->size; i++) {
+           ap_snprintf(result + (i * 2), 2 + 1, "%02x", f->bytes[i]);
+       }
+       result[i * 2] = '\0';
+    }
+    return result;
+}
+
+/*
+ *=====================================================================
+ * Convert a sting back to a feature set.
+ *
+ * am_feature_t *am_string_to_feature(char *s)
+ *
+ * entry:      s = string to convert
+ * exit:       dynamically allocated feature set
+ *
+ * Note: if the string is longer than the list of features we support,
+ * the remaining input features are ignored.  If it is shorter, the
+ * missing features are disabled.
+ *
+ * If the string is not formatted properly (not a multiple of two bytes),
+ * NULL is returned.
+ *
+ * Conversion stops at the first non-hex character.
+ *=====================================================================
+ */
+
+am_feature_t *
+am_string_to_feature(s)
+    char                       *s;
+{
+    am_feature_t               *f = NULL;
+    size_t                     i;
+    int                                ch1, ch2;
+
+    if (s != NULL && strcmp(s,"UNKNOWNFEATURE") != 0) {
+       f = am_allocate_feature_set();
+       for (i = 0; i < f->size && (ch1 = *s++) != '\0'; i++) {
+           if (isdigit(ch1)) {
+               ch1 -= '0';
+           } else if (ch1 >= 'a' && ch1 <= 'f') {
+               ch1 -= 'a';
+               ch1 += 10;
+           } else if (ch1 >= 'A' && ch1 <= 'F') {
+               ch1 -= 'a';
+               ch1 += 10;
+           } else {
+               break;
+           }
+           ch2 = *s++;
+           if (isdigit(ch2)) {
+               ch2 -= '0';
+           } else if (ch2 >= 'a' && ch2 <= 'f') {
+               ch2 -= 'a';
+               ch2 += 10;
+           } else if (ch2 >= 'A' && ch2 <= 'F') {
+               ch2 -= 'a';
+               ch2 += 10;
+           } else {
+               amfree(f);                              /* bad conversion */
+               break;
+           }
+           f->bytes[i] = (ch1 << 4) | ch2;
+       }
+    }
+    return f;
+}
+
+#if defined(TEST)
+int
+main(argc, argv)
+    int                                argc;
+    char                       **argv;
+{
+    am_feature_t               *f;
+    am_feature_t               *f1;
+    char                       *s;
+    char                       *s1;
+    int                                i;
+    int                                n;
+
+    f = am_init_feature_set();
+    if (f == NULL) {
+       fprintf(stderr, "cannot initialize feature set\n");
+       return 1;
+    }
+
+    s = am_feature_to_string(f);
+    printf("base features=%s\n", s);
+
+    f1 = am_string_to_feature(s);
+    s1 = am_feature_to_string(f1);
+    if (strcmp(s, s1) != 0) {
+       fprintf(stderr, "base feature -> string -> feature set mismatch\n");
+       fprintf(stderr, "conv features=%s\n", s);
+    }
+
+    amfree(s1);
+    amfree(s);
+
+    for (i = 1; i < argc; i++) {
+       if (argv[i][0] == '+') {
+           n = atoi(&argv[i][1]);
+           if (am_add_feature(f, (am_feature_e)n)) {
+               printf("added feature number %d\n", n);
+           } else {
+               printf("could not add feature number %d\n", n);
+           }
+       } else if (argv[i][0] == '-') {
+           n = atoi(&argv[i][1]);
+           if (am_remove_feature(f, (am_feature_e)n)) {
+               printf("removed feature number %d\n", n);
+           } else {
+               printf("could not remove feature number %d\n", n);
+           }
+       } else {
+           n = atoi(argv[i]);
+           if (am_has_feature(f, (am_feature_e)n)) {
+               printf("feature %d is set\n", n);
+           } else {
+               printf("feature %d is not set\n", n);
+           }
+       }
+    }
+
+    s = am_feature_to_string(f);
+    printf(" new features=%s\n", s);
+    amfree(s);
+
+    return 0;
+}
+#endif
diff --git a/common-src/amfeatures.h b/common-src/amfeatures.h
new file mode 100644 (file)
index 0000000..b665f2b
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * 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: amfeatures.h,v 1.1.2.6 2002/11/07 02:12:58 martinea Exp $
+ *
+ * Define feature test related items.
+ */
+
+#ifndef AMFEATURES_H
+#define AMFEATURES_H
+
+/*
+ * !!!WARNING!!!    !!!WARNING!!!    !!!WARNING!!!    !!!WARNING!!!
+ *
+ * No matter **WHAT**, you **MUST** enter new features at the **END**
+ * of this list (just before "last_feature").  If you do not, mass
+ * confusion will ensue.
+ *
+ * And features must **NEVER** be removed (that is, their code number
+ * must remain).  The bits are cheap.
+ *
+ * If you add a feature here, you probably also need to add a line to
+ * am_init_feature_set() in features.c unless it is dynamic in some way.
+ *
+ * !!!WARNING!!!    !!!WARNING!!!    !!!WARNING!!!    !!!WARNING!!!
+ */
+typedef enum {
+    /*
+     * This bit will be set if the feature test code is supported.  It
+     * will only be off for "old" (2.4.2p2 and earlier) systems.
+     */
+    have_feature_support = 0,
+
+    /*
+     * Amanda used to send authorization type information around like
+     * this in the OPTIONS string:
+     *
+     * bsd-auth
+     * krb4-auth
+     *
+     * To make it easier to add new authorization methods and parse,
+     * this was changed to a keyword=value syntax:
+     *
+     * auth=BSD
+     * auth=RSH
+     * auth=KRB4
+     * auth=krb5
+     *
+     * and so on.
+     */
+
+    fe_options_auth, /* amanda_feature_auth_keyword */
+
+    fe_selfcheck_req,
+    fe_selfcheck_req_device,
+    fe_selfcheck_rep,
+
+    fe_sendsize_req_no_options,
+    fe_sendsize_req_options,
+    fe_sendsize_req_device,            /* require fe_sendsize_req_options */
+    fe_sendsize_rep,
+
+    fe_sendbackup_req,
+    fe_sendbackup_req_device,
+    fe_sendbackup_rep,
+
+    fe_noop_req,
+    fe_noop_rep,
+
+    fe_program_dump,
+    fe_program_gnutar,
+    fe_program_dumper_api,
+
+    fe_options_compress_fast,
+    fe_options_compress_best,
+    fe_options_srvcomp_fast,
+    fe_options_srvcomp_best,
+    fe_options_no_record,
+    fe_options_index,
+    fe_options_exclude_file,
+    fe_options_exclude_list,
+    fe_options_multiple_exclude,       /* require fe_sendsize_req_options */
+    fe_options_optional_exclude,       /* require fe_sendsize_req_options */
+    fe_options_include_file,           /* require fe_sendsize_req_options */
+    fe_options_include_list,           /* require fe_sendsize_req_options */
+    fe_options_multiple_include,       /* require fe_sendsize_req_options */
+    fe_options_optional_include,       /* require fe_sendsize_req_options */
+    fe_options_bsd_auth,
+    fe_options_krb4_auth,
+    fe_options_kencrypt,
+
+    fe_req_options_maxdumps,
+    fe_req_options_hostname,
+    fe_req_options_features,
+
+    fe_rep_options_maxdumps,
+    fe_rep_options_hostname,
+    fe_rep_options_features,
+    fe_rep_options_sendbackup_options,
+
+    fe_amindexd_fileno_in_OLSD,
+    fe_amindexd_fileno_in_ORLD,
+    fe_amidxtaped_fsf,
+    fe_amidxtaped_label,
+    fe_amidxtaped_device,
+    fe_amidxtaped_host,
+    fe_amidxtaped_disk,
+    fe_amidxtaped_datestamp,
+    fe_amidxtaped_header,
+    fe_amidxtaped_nargs,
+    fe_amidxtaped_config,
+
+    /*
+     * All new features must be inserted immediately *before* this entry.
+     */
+    last_feature
+} am_feature_e;
+
+typedef struct am_feature_s {
+    size_t             size;
+    unsigned char      *bytes;
+} am_feature_t;
+
+/*
+ * 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));
+
+#endif /* !AMFEATURES_H */
diff --git a/common-src/amflock.c b/common-src/amflock.c
new file mode 100644 (file)
index 0000000..d27a857
--- /dev/null
@@ -0,0 +1,468 @@
+/*
+ * 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: amflock.c,v 1.17.4.6.6.1 2003/10/22 17:43:33 martinea Exp $
+ *
+ * file locking routines, put here to hide the system dependant stuff
+ * from the rest of the code
+ */
+/*
+**
+** Notes:
+** - These are "best effort" routines.
+** - "configure" has four variables that are used to determine which type of
+**   locking to use:
+**     USE_POSIX_FCNTL - use fcntl().  The full job.
+**     USE_FLOCK       - use flock().  Does just as well.
+**     USE_LOCKF       - use lockf().  Only handles advisory, exclusive,
+**                       blocking file locks as used by Amanda.
+**     USE_LNLOCK      - Home brew exclusive, blocking file lock.
+**     <none>          - No locking available.  User beware!
+** - "configure" compiles this with -DCONFIGURE_TEST to try and determine
+**   whether a particular type of locking works.
+*/
+
+#include "amanda.h"
+
+#if defined(USE_POSIX_FCNTL)
+     static struct flock lock; /* zero-initialized */
+#endif
+
+#if !defined(USE_POSIX_FCNTL) && defined(USE_FLOCK)
+#  ifdef HAVE_SYS_FILE_H
+#    include <sys/file.h>
+#  endif
+
+#  if !defined(HAVE_FLOCK_DECL) && !defined(CONFIGURE_TEST)
+     extern int flock P((int fd, int operation));
+#  endif
+#endif
+
+
+#if !defined(USE_POSIX_FCNTL) && !defined(USE_FLOCK) && defined(USE_LOCKF)
+
+/* XPG4-UNIX (eg, SGI IRIX, DEC DU) has F_ULOCK instead of F_UNLOCK */
+#if defined(F_ULOCK) && !defined(F_UNLOCK)
+#  define F_UNLOCK F_ULOCK
+#endif
+
+/* Lock a file using lockf().
+** Notes:
+** - 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 */
+{
+       off_t pos;
+
+       if (op) {
+               /* lock from here on */
+               if (lockf(fd, F_LOCK, (off_t)0) == -1) return -1;
+       }
+       else {
+               /* unlock from here on */
+               if (lockf(fd, F_UNLOCK, (off_t)0) == -1) return -1;
+
+               /* unlock from bof to here */
+               pos = lseek(fd, (off_t)0, SEEK_CUR);
+               if (pos == (off_t)-1) {
+                       if (errno == ESPIPE) pos = (off_t)0;
+                       else return -1;
+               }
+
+               if (pos > (off_t)0 &&
+                   lockf(fd, F_UNLOCK, -pos) == -1) return -1;
+       }
+
+       return 0;
+}
+
+#endif
+
+#if !defined(USE_POSIX_FCNTL) && !defined(USE_FLOCK) && !defined(USE_LOCKF) && defined(USE_LNLOCK)
+/* XXX - error checking in this section needs to be tightened up */
+
+/* Delete a lock file.
+*/
+int delete_lock(fn)
+char *fn;
+{
+       int rc;
+
+       rc = unlink(fn);
+       if (rc != 0 && errno == ENOENT) rc = 0;
+
+       return rc;
+}
+
+/* Create a lock file.
+*/
+int create_lock(fn, pid)
+char *fn;
+long pid;
+{
+       int fd;
+       FILE *f;
+       int mask;
+
+       (void)delete_lock(fn);                  /* that's MY file! */
+
+       mask = umask(0027);
+       fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0640);
+       umask(mask);
+       if (fd == -1) return -1;
+
+       if((f = fdopen(fd, "w")) == NULL) {
+           aclose(fd);
+           return -1;
+       }
+       fprintf(f, "%ld\n", pid);
+       if (fclose(f) == EOF)
+           return -1;
+       return 0;
+}
+
+/* Read the pid out of a lock file.
+**   -1=error, otherwise pid.
+*/
+long read_lock(fn)
+char *fn; /* name of lock file */
+{
+       int save_errno;
+       FILE *f;
+       long pid;
+
+       if ((f = fopen(fn, "r")) == NULL) {
+               return -1;
+       }
+       if (fscanf(f, "%ld", &pid) != 1) {
+               save_errno = errno;
+               afclose(f);
+               errno = save_errno;
+               return -1;
+       }
+       if (fclose(f) != 0) {
+               return -1;
+       }
+       return pid;
+}
+
+/* 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 rc;
+       int serrno;     /* saved errno */
+       struct stat lkstat, tlkstat;
+
+       /* an atomic check and set operation */
+       rc = link(tlk, lk);
+       if (rc == 0) return 0; /* XXX do we trust it? */
+
+       /* link() says it failed - don't beleive it */
+       serrno = errno;
+
+       if (stat(lk, &lkstat) == 0 &&
+           stat(tlk, &tlkstat) == 0 &&
+           lkstat.st_ino == tlkstat.st_ino)
+               return 0;       /* it did work! */
+
+       errno = serrno;
+
+       if (errno == EEXIST) rc = 1;
+
+       return rc;
+}
+
+/* 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 fd;
+       char buff[64];
+       long pid;
+       int rc;
+
+       /* prevent a race with another stealer */
+       rc = ln_lock(sres, 1);
+       if (rc != 0) goto error;
+
+       pid = read_lock(fn);
+       if (pid == -1) {
+               if (errno == ENOENT) goto done;
+               goto error;
+       }
+
+       if (pid == mypid) goto steal; /* i'm the locker! */
+
+       /* are they still there ? */
+       rc = kill((pid_t)pid, 0);
+       if (rc != 0) {
+               if (errno == ESRCH) goto steal; /* locker has gone */
+               goto error;
+       }
+
+inuse:
+       rc = ln_lock(sres, 0);
+       if (rc != 0) goto error;
+
+       return 1;
+
+steal:
+       rc = delete_lock(fn);
+       if (rc != 0) goto error;
+
+done:
+       rc = ln_lock(sres, 0);
+       if (rc != 0) goto error;
+
+       return 0;
+
+error:
+       rc = ln_lock(sres, 0);
+
+       return -1;
+}
+
+/* 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 */
+{
+       long mypid;
+       char *lockfile = NULL;
+       char *tlockfile = NULL;
+       char *mres = NULL;
+       int rc;
+       char pid_str[NUM_STR_SIZE];
+
+       mypid = (long)getpid();
+
+       lockfile = vstralloc(AMANDA_TMPDIR, "/am", res, ".lock", NULL);
+
+       if (!op) {
+               /* unlock the resource */
+               assert(read_lock(lockfile) == mypid);
+
+               (void)delete_lock(lockfile);
+               amfree(lockfile);
+               return 0;
+       }
+
+       /* lock the resource */
+
+       ap_snprintf(pid_str, sizeof(pid_str), "%ld", mypid);
+       tlockfile = vstralloc(AMANDA_TMPDIR, "am", res, ".", pid_str, NULL);
+
+       (void)create_lock(tlockfile, mypid);
+
+       mres = stralloc2(res, ".");
+
+       while(1) {
+               rc = link_lock(lockfile, tlockfile);
+               if (rc == -1) break;
+               if (rc == 0) break;
+
+               rc = steal_lock(lockfile, mypid, mres);
+               if (rc == -1) break;
+               if (rc == 0) continue;
+               sleep(1);
+       }
+
+       (void) delete_lock(tlockfile);
+
+       amfree(mres);
+       amfree(tlockfile);
+       amfree(lockfile);
+
+       return rc;
+}
+#endif
+
+
+/* Get a file lock (for read-only files).
+*/
+int amroflock(fd, resource)
+int fd;
+char *resource;
+{
+       int r;
+
+#ifdef USE_POSIX_FCNTL
+       lock.l_type = F_RDLCK;
+       lock.l_whence = SEEK_SET;
+       r = fcntl(fd, F_SETLKW, &lock);
+#else
+       r = amflock(fd, resource);
+#endif
+
+       return r;
+}
+
+
+/* Get a file lock (for read/write files).
+*/
+int amflock(fd, resource)
+int fd;
+char *resource;
+{
+       int r;
+
+#ifdef USE_POSIX_FCNTL
+       lock.l_type = F_WRLCK;
+       lock.l_whence = SEEK_SET;
+       r = fcntl(fd, F_SETLKW, &lock);
+#else
+#ifdef USE_FLOCK
+       r = flock(fd, LOCK_EX);
+#else
+#ifdef USE_LOCKF
+       r = use_lockf(fd, 1);
+#else
+#ifdef USE_LNLOCK
+       r = ln_lock(resource, 1);
+#else
+       r = 0;
+#endif
+#endif
+#endif
+#endif
+
+       return r;
+}
+
+
+/* Release a file lock.
+*/
+int amfunlock(fd, resource)
+int fd;
+char *resource;
+{
+       int r;
+
+#ifdef USE_POSIX_FCNTL
+       lock.l_type = F_UNLCK;
+       lock.l_whence = SEEK_SET;
+       r = fcntl(fd, F_SETLK, &lock);
+#else
+#ifdef USE_FLOCK
+       r = flock(fd, LOCK_UN);
+#else
+#ifdef USE_LOCKF
+       r = use_lockf(fd, 0);
+#else
+#ifdef USE_LNLOCK
+       r = ln_lock(resource, 0);
+#else
+       r = 0;
+#endif
+#endif
+#endif
+#endif
+
+       return r;
+}
+
+
+/* Test routine for use by configure.
+** (I'm not sure why we use both return and exit!)
+** XXX the testing here should be a lot more comprehensive.
+**     - lock the file and then try and lock it from another process
+**     - lock the file from another process and check that process
+**       termination unlocks it.
+**     The hard part is to find a system independent way to not block
+**     for ever.
+*/
+#ifdef CONFIGURE_TEST
+main()
+{
+    int lockfd;
+    char *filen = "/tmp/conftest.lock";
+    char *resn = "test";
+    int fd;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    unlink(filen);
+    if ((lockfd = open(filen, O_RDONLY|O_CREAT|O_EXCL, 0600)) == -1) {
+       perror (filen);
+       exit(10);
+    }
+
+    if (amroflock(lockfd, resn) != 0) {
+       perror ("amroflock");
+       exit(1);
+    }
+    if (amfunlock(lockfd, resn) != 0) {
+       perror ("amfunlock/2");
+       exit(2);
+    }
+
+    /*
+     * Do not use aclose() here.  During configure we do not have
+     * areads_relbuf() available and it makes configure think all
+     * the tests have failed.
+     */
+    close(lockfd);
+
+    unlink(filen);
+    if ((lockfd = open(filen, O_WRONLY|O_CREAT|O_EXCL, 0600)) == -1) {
+       perror (filen);
+       exit(20);
+    }
+
+    if (amflock(lockfd, resn) != 0) {
+       perror ("amflock");
+       exit(3);
+    }
+    if (amfunlock(lockfd, resn) != 0) {
+       perror ("amfunlock/4");
+       exit(4);
+    }
+
+    close(lockfd);
+
+    exit(0);
+}
+#endif
diff --git a/common-src/amregex.h b/common-src/amregex.h
new file mode 100644 (file)
index 0000000..f606ea2
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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: amregex.h,v 1.9 1998/07/04 00:18:36 oliva Exp $
+ *
+ * compatibility header file for Henry Spencer's regex library.
+ */
+#ifndef AMREGEX_H
+#define AMREGEX_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include <limits.h>
+
+#ifndef HAVE__POSIX2_RE_DUP_MAX
+#define _POSIX2_RE_DUP_MAX 255
+#endif
+
+#ifndef HAVE_CHAR_MIN
+#define CHAR_MIN (-128)
+#endif
+
+#ifndef HAVE_CHAR_MAX
+#define CHAR_MAX 127
+#endif
+
+#ifndef HAVE_CHAR_BIT
+#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 ...
+ * it may work on earlier stuff, but why chance it.
+ */
+#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7
+#define __attribute__(__x)
+#endif
+
+#ifndef HAVE_BCOPY_DECL
+extern void bcopy P((const void *from, void *to, size_t n));
+#endif
+
+#ifndef HAVE_MEMMOVE_DECL
+extern char *memmove P((char *to, char *from, size_t n));
+#endif
+
+#ifndef HAVE_MEMSET_DECL
+extern void *memset P((void *s, int c, size_t n));
+#endif
+
+#if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY)
+#define USEBCOPY
+#endif
+
+#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF)
+#define ap_snprintf    snprintf
+#define ap_vsnprintf   vsnprintf
+#endif
+#ifndef HAVE_SNPRINTF_DECL
+#include "arglist.h"
+int ap_snprintf  P((char *buf, size_t len, const char *format,...))
+                   __attribute__((format(printf,3,4)));
+#endif
+#ifndef HAVE_VSNPRINTF_DECL
+#include "arglist.h"
+int ap_vsnprintf P((char *buf, size_t len, const char *format, va_list ap));
+#endif
+
+#define POSIX_MISTAKE
+
+#ifdef HAVE_UNSIGNED_LONG_CONSTANTS
+#undef NO_UL_CNSTS
+#else
+#define NO_UL_CNSTS
+#endif
+
+#endif /* AMREGEX_H */
diff --git a/common-src/arglist.h b/common-src/arglist.h
new file mode 100644 (file)
index 0000000..e26f714
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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: arglist.h,v 1.4.10.2 2002/12/03 21:36:47 martinea Exp $
+ *
+ * support macros for variable argument list declaration and definition
+ */
+
+#ifndef ARGLIST_H
+#define ARGLIST_H
+
+#ifdef STDC_HEADERS
+
+#include <stdarg.h>
+
+#define printf_arglist_function(fdecl, \
+                               hook_type, hook_name) \
+       __attribute__ ((format (printf, 1, 0))) \
+        fdecl(hook_type hook_name, ...)
+
+#define printf_arglist_function1(fdecl, \
+                                arg1_type, arg1_name, \
+                                hook_type, hook_name) \
+       __attribute__ ((format (printf, 2, 0))) \
+       fdecl(arg1_type arg1_name, \
+             hook_type hook_name, ...)
+
+#define printf_arglist_function2(fdecl, \
+                                arg1_type, arg1_name, \
+                                arg2_type, arg2_name, \
+                                hook_type, hook_name) \
+       __attribute__ ((format (printf, 3, 0))) \
+       fdecl(arg1_type arg1_name, \
+             arg2_type arg2_name, \
+             hook_type hook_name, ...)
+
+#define arglist_function(fdecl, \
+                        hook_type, hook_name) \
+        fdecl(hook_type hook_name, ...)
+
+#define arglist_function1(fdecl, \
+                         arg1_type, arg1_name, \
+                         hook_type, hook_name) \
+       fdecl(arg1_type arg1_name, \
+             hook_type hook_name, ...)
+
+#define arglist_function2(fdecl, \
+                         arg1_type, arg1_name, \
+                         arg2_type, arg2_name, \
+                         hook_type, hook_name) \
+       fdecl(arg1_type arg1_name, \
+             arg2_type arg2_name, \
+             hook_type hook_name, ...)
+
+#define arglist_start(arg,hook_name)   va_start(arg,hook_name)
+
+#else
+
+#include <varargs.h>
+
+#define printf_arglist_function(fdecl, hook_type, hook_name) \
+        fdecl(hook_name, va_alist)     \
+        hook_type hook_name;           \
+        va_dcl
+
+#define printf_arglist_function1(fdecl, arg1_type, arg1_name, hook_type, hook_name) \
+       fdecl(arg1_name, hook_name, va_alist)   \
+       arg1_type arg1_name;                    \
+       hook_type hook_name;                    \
+       va_dcl
+
+#define printf_arglist_function2(fdecl, arg1_type, arg1_name, arg2_type, arg2_name, hook_type, hook_name) \
+       fdecl(arg1_name, arg2_name, hook_name, va_alist)        \
+       arg1_type arg1_name;                                    \
+       arg2_type arg2_name;                                    \
+       hook_type hook_name;                                    \
+       va_dcl
+
+#define arglist_function(fdecl, hook_type, hook_name) \
+        fdecl(hook_name, va_alist)     \
+        hook_type hook_name;           \
+        va_dcl
+
+#define arglist_function1(fdecl, arg1_type, arg1_name, hook_type, hook_name) \
+       fdecl(arg1_name, hook_name, va_alist)   \
+       arg1_type arg1_name;                    \
+       hook_type hook_name;                    \
+       va_dcl
+
+#define arglist_function2(fdecl, arg1_type, arg1_name, arg2_type, arg2_name, hook_type, hook_name) \
+       fdecl(arg1_name, arg2_name, hook_name, va_alist)        \
+       arg1_type arg1_name;                                    \
+       arg2_type arg2_name;                                    \
+       hook_type hook_name;                                    \
+       va_dcl
+
+#define arglist_start(arg,hook_name)   va_start(arg)
+
+#endif
+
+#define arglist_val(arg,type)  va_arg(arg,type)
+#define arglist_end(arg)       va_end(arg)
+
+#endif /* !ARGLIST_H */
diff --git a/common-src/clock.c b/common-src/clock.c
new file mode 100644 (file)
index 0000000..840992f
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: clock.c,v 1.2.2.2 2002/03/31 21:01:33 jrjackson Exp $
+ *
+ * timing functions
+ */
+#include "amanda.h"
+
+#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));
+
+times_t times_zero = {{0,0}};
+times_t start_time;
+static int clock_running = 0;
+
+#ifdef HAVE_TWO_ARG_GETTIMEOFDAY
+#  define amanda_gettimeofday(x, y) gettimeofday((x), (y))
+#else
+#  define amanda_gettimeofday(x, y) gettimeofday((x))
+#endif
+
+int clock_is_running()
+{
+    return clock_running;
+}
+
+void startclock()
+{
+#ifdef HAVE_TWO_ARG_GETTIMEOFDAY
+    struct timezone dontcare;
+#endif
+
+    clock_running = 1;
+    amanda_gettimeofday(&start_time.r, &dontcare);
+}
+
+times_t stopclock()
+{
+    times_t diff;
+    struct timeval end_time;
+
+#ifdef HAVE_TWO_ARG_GETTIMEOFDAY
+    struct timezone dontcare;
+#endif
+
+    if(!clock_running) {
+       fprintf(stderr,"stopclock botch\n");
+       exit(1);
+    }
+    amanda_gettimeofday(&end_time, &dontcare);
+    diff.r = timesub(end_time,start_time.r);
+    clock_running = 0;
+    return diff;
+}
+
+times_t curclock()
+{
+    times_t diff;
+    struct timeval end_time;
+
+#ifdef HAVE_TWO_ARG_GETTIMEOFDAY
+    struct timezone dontcare;
+#endif
+
+    if(!clock_running) {
+       fprintf(stderr,"curclock botch\n");
+       exit(1);
+    }
+    amanda_gettimeofday(&end_time, &dontcare);
+    diff.r = timesub(end_time,start_time.r);
+    return diff;
+}
+
+times_t timesadd(a,b)
+times_t a,b;
+{
+    times_t sum;
+
+    sum.r = timeadd(a.r,b.r);
+    return sum;
+}
+
+times_t timessub(a,b)
+times_t a,b;
+{
+    times_t dif;
+
+    dif.r = timesub(a.r,b.r);
+    return dif;
+}
+
+char *times_str(t)
+times_t t;
+{
+    static char str[10][NUM_STR_SIZE+10];
+    static int n = 0;
+    char *s;
+
+    /* tv_sec/tv_usec are longs on some systems */
+    ap_snprintf(str[n], sizeof(str[n]),
+               "rtime %d.%03d", (int)t.r.tv_sec, (int)t.r.tv_usec/1000);
+    s = str[n++];
+    n %= am_countof(str);
+    return s;
+}
+
+char *walltime_str(t)
+times_t t;
+{
+    static char str[10][NUM_STR_SIZE+10];
+    static int n = 0;
+    char *s;
+
+    /* tv_sec/tv_usec are longs on some systems */
+    ap_snprintf(str[n], sizeof(str[n]),
+               "%d.%03d", (int)t.r.tv_sec, (int)t.r.tv_usec/1000);
+    s = str[n++];
+    n %= am_countof(str);
+    return s;
+}
+
+static struct timeval timesub(end,start)
+struct timeval end,start;
+{
+    struct timeval diff;
+
+    if(end.tv_usec < start.tv_usec) { /* borrow 1 sec */
+       end.tv_sec -= 1;
+       end.tv_usec += 1000000;
+    }
+    diff.tv_usec = end.tv_usec - start.tv_usec;
+    diff.tv_sec = end.tv_sec - start.tv_sec;
+    return diff;
+}
+
+static struct timeval timeadd(a,b)
+struct timeval a,b;
+{
+    struct timeval sum;
+
+    sum.tv_sec = a.tv_sec + b.tv_sec;
+    sum.tv_usec = a.tv_usec + b.tv_usec;
+
+    if(sum.tv_usec >= 1000000) {
+       sum.tv_usec -= 1000000;
+       sum.tv_sec += 1;
+    }
+    return sum;
+}
diff --git a/common-src/clock.h b/common-src/clock.h
new file mode 100644 (file)
index 0000000..8d3922e
--- /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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: clock.h,v 1.2.2.2 2002/03/31 21:01:33 jrjackson Exp $
+ *
+ * interface for timing functions
+ */
+#ifndef CLOCK_H
+#define CLOCK_H
+
+#include "amanda.h"
+
+typedef struct times_s {
+    struct timeval r;
+
+#ifdef INSTRUMENTATION
+    struct timeval u,s;
+#endif
+} times_t;
+
+extern times_t times_zero, start_time;
+
+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));
+
+#endif /* CLOCK_H */
diff --git a/common-src/debug.c b/common-src/debug.c
new file mode 100644 (file)
index 0000000..ced7bc1
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: debug.c,v 1.17.4.3.4.3.2.9 2003/01/04 17:46:09 martinea Exp $
+ *
+ * debug log subroutines
+ */
+
+#include "amanda.h"
+#include "clock.h"
+#include "util.h"
+#include "arglist.h"
+
+#ifndef AMANDA_DBGDIR
+#  define AMANDA_DBGDIR                AMANDA_TMPDIR
+#endif
+
+#ifdef DEBUG_CODE
+
+int debug = 1;
+
+#define        MIN_DB_FD                       10
+
+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 pid_t debug_prefix_pid = 0;
+
+/*
+ * Format and write a debug message to the process debug file.
+ */
+printf_arglist_function(void debug_printf, char *, format)
+{
+    va_list argp;
+    int save_errno;
+
+    /*
+     * It is common in the code to call dbprintf to write out
+     * syserrno(errno) and then turn around and try to do something else
+     * 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(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;
+}
+
+/*
+ * Generate a debug file name.  The name is based on the program name,
+ * followed by a timestamp, an optional sequence number, and ".debug".
+ */
+static char *
+get_debug_name(t, n)
+    time_t t;
+    int n;
+{
+    char number[NUM_STR_SIZE];
+    char *ts;
+    char *result;
+
+    if(n < 0 || n > 1000) {
+       return NULL;
+    }
+    ts = construct_timestamp(&t);
+    if(n == 0) {
+       number[0] = '\0';
+    } else {
+       ap_snprintf(number, sizeof(number), "%03d", n - 1);
+    }
+    result = vstralloc(get_pname(), ".", ts, number, ".debug", NULL);
+    amfree(ts);
+    return result;
+}
+
+void debug_open()
+{
+    time_t curtime;
+    int saved_debug;
+    char *dbgdir = NULL;
+    char *e = NULL;
+    char *s = NULL;
+    char *dbfilename = NULL;
+    DIR *d;
+    struct dirent *entry;
+    char *pname;
+    size_t pname_len;
+    int do_rename;
+    char *test_name = NULL;
+    size_t test_name_len;
+    int fd = -1;
+    int i;
+    size_t d_name_len;
+    int fd_close[MIN_DB_FD+1];
+    struct passwd *pwent;
+    struct stat sbuf;
+
+    pname = get_pname();
+    pname_len = strlen(pname);
+
+    if(client_uid == (uid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) {
+       client_uid = pwent->pw_uid;
+       client_gid = pwent->pw_gid;
+       endpwent();
+    }
+
+    /*
+     * Create the debug directory if it does not yet exist.
+     */
+    dbgdir = stralloc2(AMANDA_DBGDIR, "/");
+    if(mkpdir(dbgdir, 02700, client_uid, client_gid) == -1) {
+        error("create debug directory \"%s\": %s",
+             AMANDA_DBGDIR, strerror(errno));
+    }
+
+    /*
+     * Clean out old debug files.  We also rename files with old style
+     * names (XXX.debug or XXX.$PID.debug) into the new name format.
+     * We assume no system has 17 digit PID-s :-) and that there will
+     * not be a conflict between an old and new name.
+     */
+    if((d = opendir(AMANDA_DBGDIR)) == NULL) {
+        error("open debug directory \"%s\": %s",
+             AMANDA_DBGDIR, strerror(errno));
+    }
+    time(&curtime);
+    test_name = get_debug_name(curtime - (AMANDA_DEBUG_DAYS * 24 * 60 * 60), 0);
+    test_name_len = strlen(test_name);
+    while((entry = readdir(d)) != NULL) {
+       if(is_dot_or_dotdot(entry->d_name)) {
+           continue;
+       }
+       d_name_len = strlen(entry->d_name);
+       if(strncmp(entry->d_name, pname, pname_len) != 0
+          || entry->d_name[pname_len] != '.'
+          || d_name_len < 6
+          || strcmp(entry->d_name + d_name_len - 6, ".debug") != 0) {
+           continue;                           /* not one of our debug files */
+       }
+       e = newvstralloc(e, dbgdir, entry->d_name, NULL);
+       if(d_name_len < test_name_len) {
+           /*
+            * Create a "pretend" name based on the last modification
+            * time.  This name will be used to decide if the real name
+            * should be removed.  If not, it will be used to rename the
+            * real name.
+            */
+           if(stat(e, &sbuf) != 0) {
+               continue;                       /* ignore errors */
+           }
+           amfree(dbfilename);
+           dbfilename = get_debug_name((time_t)sbuf.st_mtime, 0);
+           do_rename = 1;
+       } else {
+           dbfilename = newstralloc(dbfilename, entry->d_name);
+           do_rename = 0;
+       }
+       if(strcmp(dbfilename, test_name) < 0) {
+           (void) unlink(e);                   /* get rid of old file */
+           continue;
+       }
+       if(do_rename) {
+           i = 0;
+           while(dbfilename != NULL
+                 && (s = newvstralloc(s, dbgdir, dbfilename, NULL)) != NULL
+                 && rename(e, s) != 0 && errno != ENOENT) {
+               amfree(dbfilename);
+               dbfilename = get_debug_name((time_t)sbuf.st_mtime, ++i);
+           }
+           if(dbfilename == NULL) {
+               error("cannot rename old debug file \"%s\"", entry->d_name);
+           }
+       }
+    }
+    amfree(dbfilename);
+    amfree(e);
+    amfree(s);
+    amfree(test_name);
+    closedir(d);
+
+    /*
+     * Create the new file.
+     */
+    for(i = 0;
+       (dbfilename = get_debug_name(curtime, i)) != NULL
+       && (s = newvstralloc(s, dbgdir, dbfilename, NULL)) != NULL
+       && (fd = open(s, O_WRONLY|O_CREAT|O_EXCL|O_APPEND, 0600)) < 0;
+       i++, free(dbfilename)) {}
+    if(dbfilename == NULL) {
+       error("cannot create %s debug file", get_pname());
+    }
+    amfree(dbfilename);
+    amfree(db_filename);
+    db_filename = s;
+    s = NULL;
+    (void) chown(db_filename, client_uid, client_gid);
+    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]);
+    }
+    db_file = fdopen(db_fd, "a");
+
+    /*
+     * Make the first debug log file entry.
+     */
+    saved_debug = debug; debug = 1;
+    debug_printf("%s: debug %d pid %ld ruid %ld euid %ld: start at %s",
+                pname, saved_debug, (long)getpid(),
+                (long)getuid(), (long)geteuid(),
+                ctime(&curtime));
+    debug = saved_debug;
+}
+
+void debug_close()
+{
+    time_t curtime;
+    int save_debug;
+    pid_t save_pid;
+
+    time(&curtime);
+    save_debug = debug;
+    debug = 1;
+    save_pid = debug_prefix_pid;
+    debug_prefix_pid = 0;
+    debug_printf("%s: pid %ld finish time %s",
+                debug_prefix_time(NULL),
+                (long)getpid(),
+                ctime(&curtime));
+    debug_prefix_pid = save_pid;
+    debug = save_debug;
+
+    if(db_file && fclose(db_file) == EOF) {
+       int save_errno = errno;
+
+       db_file = NULL;                         /* prevent recursion */
+       error("close debug file: %s", strerror(save_errno));
+    }
+    db_fd = -1;
+    db_file = NULL;
+    amfree(db_filename);
+}
+
+int debug_fd()
+{
+    return db_fd;
+}
+
+FILE *debug_fp()
+{
+    return db_file;
+}
+
+char *debug_fn()
+{
+    return db_filename;
+}
+
+/*
+ * Routines for returning a common debug file line prefix.  Always starts
+ * with the current program name, possibly with an optional suffix.
+ * May then be followed by a PID.  May then be followed by an elapsed
+ * time indicator.
+ */ 
+
+void set_debug_prefix_pid(p)
+    pid_t p;
+{
+    debug_prefix_pid = p;
+}
+
+char *debug_prefix(suffix)
+    char *suffix;
+{
+    static char *s = NULL;
+    char debug_pid[NUM_STR_SIZE];
+
+    s = newvstralloc(s, get_pname(), suffix, NULL);
+    if (debug_prefix_pid != (pid_t) 0) {
+       ap_snprintf(debug_pid, sizeof(debug_pid),
+                   "%ld",
+                   (long) debug_prefix_pid);
+       s = newvstralloc(s, s, "[", debug_pid, "]", NULL);
+    }
+    return s;
+}
+
+char *debug_prefix_time(suffix)
+    char *suffix;
+{
+    static char *s = NULL;
+    char *t1;
+    char *t2;
+
+    if (clock_is_running()) {
+       t1 = ": time ";
+       t2 = walltime_str(curclock());
+    } else {
+       t1 = t2 = NULL;
+    }
+
+    s = newvstralloc(s, debug_prefix(suffix), t1, t2, NULL);
+
+    return s;
+}
+#endif
diff --git a/common-src/dgram.c b/common-src/dgram.c
new file mode 100644 (file)
index 0000000..60ba123
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/* 
+ * $Id: dgram.c,v 1.11.2.3.4.3.2.4 2002/11/12 19:19:03 martinea Exp $
+ *
+ * library routines to marshall/send, recv/unmarshall UDP packets
+ */
+#include "amanda.h"
+#include "dgram.h"
+#include "util.h"
+
+void dgram_socket(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);
+    }
+    dgram->socket = socket;
+}
+
+
+int dgram_bind(dgram, portp)
+dgram_t *dgram;
+int *portp;
+{
+    int s;
+    socklen_t len;
+    struct sockaddr_in name;
+    int save_errno;
+
+    if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+       save_errno = errno;
+       dbprintf(("%s: dgram_bind: socket() failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       errno = save_errno;
+       return -1;
+    }
+    if(s < 0 || s >= FD_SETSIZE) {
+       dbprintf(("%s: dgram_bind: socket out of range: %d\n",
+                 debug_prefix(NULL),
+                 s));
+       aclose(s);
+       errno = EMFILE;                         /* out of range */
+       return -1;
+    }
+
+    memset(&name, 0, sizeof(name));
+    name.sin_family = AF_INET;
+    name.sin_addr.s_addr = INADDR_ANY;
+
+    /*
+     * 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
+     * fails, we just go for any port.
+     *
+     * It is up to the caller to make sure we have the proper permissions
+     * to get the desired port, and to make sure we return a port that
+     * is within the range it requires.
+     */
+#ifdef UDPPORTRANGE
+    if (bind_portrange(s, &name, UDPPORTRANGE) == 0)
+       goto out;
+#endif
+
+    if (bind_portrange(s, &name, 512, IPPORT_RESERVED - 1) == 0)
+       goto out;
+
+    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",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       errno = save_errno;
+       aclose(s);
+       return -1;
+    }
+
+out:
+    /* find out what name was actually used */
+
+    len = (socklen_t) sizeof name;
+    if(getsockname(s, (struct sockaddr *)&name, &len) == -1) {
+       save_errno = errno;
+       dbprintf(("%s: dgram_bind: getsockname() failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       errno = save_errno;
+       aclose(s);
+       return -1;
+    }
+    *portp = ntohs(name.sin_port);
+    dgram->socket = s;
+    dbprintf(("%s: dgram_bind: socket bound to %s.%d\n",
+             debug_prefix_time(NULL),
+             inet_ntoa(name.sin_addr),
+             *portp));
+    return 0;
+}
+
+
+int dgram_send_addr(addr, dgram)
+struct sockaddr_in addr;
+dgram_t *dgram;
+{
+    int s;
+    int socket_opened;
+    struct sockaddr_in addr_save;
+    int save_errno;
+    int max_wait;
+    int wait_count;
+
+    if(dgram->socket != -1) {
+       s = dgram->socket;
+       socket_opened = 0;
+    } else {
+       if((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+           save_errno = errno;
+           dbprintf(("%s: dgram_send_addr: socket() failed: %s\n",
+                     debug_prefix(NULL),
+                     strerror(save_errno)));
+           errno = save_errno;
+           return -1;
+       }
+       socket_opened = 1;
+    }
+
+    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,
+                dgram->data,
+                dgram->len,
+                0, 
+                (struct sockaddr *)&addr,
+                (socklen_t) 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",
+                     debug_prefix_time(NULL),
+                     inet_ntoa(addr_save.sin_addr),
+                     (int) ntohs(addr.sin_port),
+                     wait_count));
+           continue;
+       }
+#endif
+       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;
+    }
+
+    if(socket_opened) {
+       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;
+       }
+       s = -1;
+    }
+
+    return 0;
+}
+
+
+int dgram_send(hostname, port, dgram)
+char *hostname;
+int port;
+dgram_t *dgram;
+{
+    struct sockaddr_in name;
+    struct hostent *hp;
+    int save_errno;
+
+    if((hp = gethostbyname(hostname)) == 0) {
+       save_errno = errno;
+       dbprintf(("%s: dgram_send: gethostbyname(%s) failed\n",
+                 debug_prefix_time(NULL),
+                 hostname));
+       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);
+
+    return dgram_send_addr(name, dgram);
+}
+
+
+int dgram_recv(dgram, timeout, fromaddr)
+dgram_t *dgram;
+int timeout;
+struct sockaddr_in *fromaddr;
+{
+    fd_set ready;
+    struct timeval to;
+    ssize_t size;
+    int sock;
+    socklen_t addrlen;
+    int nfound;
+    int save_errno;
+
+    sock = dgram->socket;
+
+    FD_ZERO(&ready);
+    FD_SET(sock, &ready);
+    to.tv_sec = timeout;
+    to.tv_usec = 0;
+
+    nfound = select(sock+1, (SELECT_ARG_TYPE *)&ready, NULL, NULL, &to);
+    if(nfound <= 0 || !FD_ISSET(sock, &ready)) {
+       save_errno = errno;
+       if(nfound < 0) {
+           dbprintf(("%s: dgram_recv: select() failed: %s\n",
+                     debug_prefix_time(NULL),
+                     strerror(save_errno)));
+       } else if(nfound == 0) {
+           dbprintf(("%s: dgram_recv: timeout after %d second%s\n",
+                     debug_prefix_time(NULL),
+                     timeout,
+                     (timeout == 1) ? "" : "s"));
+           nfound = 0;
+       } else if (!FD_ISSET(sock, &ready)) {
+           int i;
+
+           for(i = 0; i < sock + 1; i++) {
+               if(FD_ISSET(i, &ready)) {
+                   dbprintf(("%s: dgram_recv: got fd %d instead of %d\n",
+                             debug_prefix_time(NULL),
+                             i,
+                             sock));
+               }
+           }
+           save_errno = EBADF;
+           nfound = -1;
+       }
+       errno = save_errno;
+       return nfound;
+    }
+
+    addrlen = (socklen_t) sizeof(struct sockaddr_in);
+    size = recvfrom(sock, dgram->data, MAX_DGRAM, 0,
+                   (struct sockaddr *)fromaddr, &addrlen);
+    if(size == -1) {
+       save_errno = errno;
+       dbprintf(("%s: dgram_recv: recvfrom() failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       errno = save_errno;
+       return -1;
+    }
+    dgram->len = size;
+    dgram->data[size] = '\0';
+    dgram->cur = dgram->data;
+    return size;
+}
+
+
+void dgram_zero(dgram)
+dgram_t *dgram;
+{
+    dgram->cur = dgram->data;
+    dgram->len = 0;
+    *(dgram->cur) = '\0';
+}
+
+dgram_t *debug_dgram_alloc(s, l)
+char *s;
+int l;
+{
+    dgram_t *p;
+
+    malloc_enter(dbmalloc_caller_loc(s, l));
+    p = (dgram_t *) alloc(sizeof(dgram_t));
+    dgram_zero(p);
+    p->socket = -1;
+    malloc_leave(dbmalloc_caller_loc(s, l));
+
+    return p;
+}
+
+
+void dgram_cat(dgram, str)
+dgram_t *dgram;
+const char *str;
+{
+    int len = strlen(str);
+
+    if(dgram->len + len > MAX_DGRAM) len = MAX_DGRAM - dgram->len;
+    strncpy(dgram->cur, str, len);
+    dgram->cur += len;
+    dgram->len += len;
+    *(dgram->cur) = '\0';
+}
+
+void dgram_eatline(dgram)
+dgram_t *dgram;
+{
+    char *p = dgram->cur;
+    char *end = dgram->data + dgram->len;
+
+    while(p < end && *p && *p != '\n') p++;
+    if(*p == '\n') p++;
+    dgram->cur = p;
+}
diff --git a/common-src/dgram.h b/common-src/dgram.h
new file mode 100644 (file)
index 0000000..6a58346
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: dgram.h,v 1.6.2.2.4.1.2.1 2002/03/24 19:23:23 jrjackson Exp $
+ *
+ * interface for datagram module
+ */
+#ifndef DGRAM_H
+#define DGRAM_H
+
+#include "amanda.h"
+
+/*
+ * Maximum datagram (UDP packet) we can generate.  Size is limited by
+ * a 16 bit length field in an IPv4 header (65535), which must include
+ * the 24 byte IP header and the 8 byte UDP header.
+ */
+#define MAX_DGRAM      (((1<<16)-1)-24-8)
+
+typedef struct dgram_s {
+    char *cur;
+    int socket;
+    int 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 *str));
+void dgram_eatline P((dgram_t *dgram));
+
+extern dgram_t  *debug_dgram_alloc  P((char *c, int l));
+
+#define        dgram_alloc()           debug_dgram_alloc(__FILE__, __LINE__)
+
+#endif /* ! DGRAM_H */
diff --git a/common-src/error.c b/common-src/error.c
new file mode 100644 (file)
index 0000000..5ce8b46
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: error.c,v 1.8.4.1.2.2.2.4 2003/04/27 01:17:50 martinea Exp $
+ *
+ * error handling common to Amanda programs
+ */
+#include "amanda.h"
+#include "arglist.h"
+
+#define MAXFUNCS 8
+
+typedef void (*voidfunc) P((void));
+static voidfunc onerr[MAXFUNCS] = 
+    { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+
+int erroutput_type = ERR_INTERACTIVE;
+
+static char *pname = "unknown";
+
+static void (*logerror) P((char *)) = NULL;
+
+void set_pname(p)
+char *p;
+{
+    pname = p;
+}
+
+char *get_pname()
+{
+    return pname;
+}
+
+void set_logerror(f)
+void (*f) P((char *));
+{
+    logerror = f;
+}
+
+
+static void output_error_message(msg)
+char *msg;
+{
+    /* print and/or log message */
+
+    if((erroutput_type & ERR_AMANDALOG) != 0 && logerror != NULL) {
+       (*logerror)(msg);
+    }
+
+    if(erroutput_type & ERR_SYSLOG) {
+#ifdef LOG_AUTH
+       openlog(get_pname(), LOG_PID, LOG_AUTH);
+#else
+       openlog(get_pname(), LOG_PID);
+#endif
+       syslog(LOG_NOTICE, "%s", msg);
+       closelog();
+    }
+
+    if(erroutput_type & ERR_INTERACTIVE) {
+       fprintf(stderr, "%s: %s\n", get_pname(), msg);
+       fflush(stderr);
+    }
+
+    if(dbfp() != NULL) {
+       dbprintf(("%s: %s\n", debug_prefix_time(NULL), msg));
+       dbclose();
+    }
+}
+
+
+/*
+ * Prints an error message, calls the functions installed via onerror(),
+ * then exits.
+ */
+printf_arglist_function(void error, char *, format)
+{
+    va_list argp;
+    int i;
+    char linebuf[STR_SIZE];
+
+
+    /* format and output the error message */
+
+    arglist_start(argp, format);
+    ap_vsnprintf(linebuf, sizeof(linebuf), format, argp);
+    arglist_end(argp);
+    output_error_message(linebuf);
+
+    /* traverse function list, calling in reverse order */
+
+    for(i=MAXFUNCS-1; i >= 0; i--) {
+       if(onerr[i] != NULL) (*onerr[i])();
+    }
+
+    /* terminate */
+    exit(1);
+}
+
+
+/*
+ * Prints an error message, calls the functions installed via onerror(),
+ * then calls abort() to drop core.
+ */
+printf_arglist_function(void errordump, char *, format)
+{
+    va_list argp;
+    int i;
+    char linebuf[STR_SIZE];
+
+    /* format error message */
+
+    arglist_start(argp, format);
+    ap_vsnprintf(linebuf, sizeof(linebuf), format, argp);
+    arglist_end(argp);
+    output_error_message(linebuf);
+
+    /* traverse function list, calling in reverse order */
+
+    for(i=MAXFUNCS-1; i >= 0; i--) {
+       if(onerr[i] != NULL) (*onerr[i])();
+    }
+
+    /* terminate and drop core */
+    abort();
+}
+
+
+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
+ * returns -1, otherwise it returns 0.
+ *
+ * The resemblance to atexit() is on purpose.  I wouldn't need onerror()
+ * if everyone had atexit().  Bummer.
+ */
+{
+    int i;
+
+    for(i=0; i < MAXFUNCS; i++)                /* find empty slot */
+       if(onerr[i] == NULL) {
+           onerr[i] = errf;
+           return 0;
+       }
+
+    return -1;                         /* full table */
+}
diff --git a/common-src/file.c b/common-src/file.c
new file mode 100644 (file)
index 0000000..a7a418d
--- /dev/null
@@ -0,0 +1,674 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1997-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: AMANDA core development group.
+ */
+/*
+ * $Id: file.c,v 1.14.4.6.4.2.2.5 2003/01/01 23:28:52 martinea Exp $
+ *
+ * file and directory bashing routines
+ */
+
+#include "amanda.h"
+#include "util.h"
+
+uid_t client_uid = (uid_t) -1;
+gid_t client_gid = (gid_t) -1;
+
+/* Make a directory (internal function).
+** If the directory already exists then we pretend we created it.
+** XXX - I'm not sure about the use of the chown() stuff.  On most systems
+**       it will do nothing - only root is permitted to change the owner
+**       of a file.
+*/
+int mk1dir(dir, mode, uid, gid)
+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 */
+{
+    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? */
+    } else {                   /* maybe someone beat us to it */
+       int serrno;
+
+       serrno = errno;
+       if(access(dir, F_OK) != 0) rc = -1;
+       errno = serrno; /* pass back the real error */
+    }
+
+    return rc;
+}
+
+
+/*
+ * Make a directory hierarchy given an entry to be created (by the caller)
+ * in the new target.  In other words, create all the directories down to
+ * 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 */
+{
+    char *dir = NULL, *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';
+
+       if(access(dir, F_OK) != 0) {    /* doesn't exist */
+           if(mkpdir(dir, mode, uid, gid) != 0 ||
+              mk1dir(dir, mode, uid, gid) != 0) rc = -1; /* create failed */
+       }
+    }
+
+    amfree(dir);
+    return rc;
+}
+
+
+/* Remove as much of a directory hierarchy as possible.
+** Notes:
+**  - assumes that rmdir() on a non-empty directory will fail!
+**  - 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 rc;
+    char *p, *dir = NULL;
+
+    if(strcmp(file, topdir) == 0) return 0; /* all done */
+
+    rc = rmdir(file);
+    if (rc != 0) switch(errno) {
+#ifdef ENOTEMPTY
+#if ENOTEMPTY != EEXIST                        /* AIX makes these the same */
+       case ENOTEMPTY:
+#endif
+#endif
+       case EEXIST:    /* directory not empty */
+           return 0; /* cant do much more */
+       case ENOENT:    /* it has already gone */
+           rc = 0; /* ignore */
+           break;
+       case ENOTDIR:   /* it was a file */
+           rc = unlink(file);
+           break;
+       }
+
+    if(rc != 0) return -1; /* unexpected error */
+
+    dir = stralloc(file);
+
+    p = strrchr(dir, '/');
+    if(p == dir) rc = 0; /* no /'s */
+    else {
+       *p = '\0';
+
+       rc = rmpdir(dir, topdir);
+    }
+
+    amfree(dir);
+
+    return rc;
+}
+
+
+/*
+ *=====================================================================
+ * Do Amanda setup for all programs.
+ *
+ * void amanda_setup (int argc, char **argv, int setup_flags)
+ *
+ * entry:      setup_flags (see AMANDA_SETUP_FLAG_xxx)
+ * exit:       none
+ *=====================================================================
+ */
+
+void
+amanda_setup (argc, argv, setup_flags)
+    int                        argc;
+    char               **argv;
+    int                        setup_flags;
+{
+}
+
+/*
+ *=====================================================================
+ * Change directory to a "safe" location and set some base environment.
+ *
+ * void safe_cd (void)
+ *
+ * entry:      client_uid and client_gid set to CLIENT_LOGIN information
+ * exit:       none
+ *
+ * Set a default umask of 0077.
+ *
+ * Create the Amada debug directory (if defined) and the Amanda temp
+ * directory.
+ *
+ * Try to chdir to the Amanda debug directory first, but it must be owned
+ * by the Amanda user and not allow rwx to group or other.  Otherwise,
+ * try the same thing to the Amanda temp directory.
+ *
+ * If that is all OK, call save_core().
+ *
+ * Otherwise, cd to "/" so if we take a signal we cannot drop core
+ * unless the system administrator has made special arrangements (e.g.
+ * pre-created a core file with the right ownership and permissions).
+ *=====================================================================
+ */
+
+void
+safe_cd()
+{
+    int                        cd_ok = 0;
+    struct stat                sbuf;
+    struct passwd      *pwent;
+    char               *d;
+
+    if(client_uid == (uid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) {
+       client_uid = pwent->pw_uid;
+       client_gid = pwent->pw_gid;
+       endpwent();
+    }
+
+    (void) umask(0077);
+
+    if (client_uid != (uid_t) -1) {
+#if defined(AMANDA_DBGDIR)
+       d = stralloc2(AMANDA_DBGDIR, "/.");
+       (void) mkpdir(d, 02700, client_uid, client_gid);
+       amfree(d);
+#endif
+       d = stralloc2(AMANDA_TMPDIR, "/.");
+       (void) mkpdir(d, 02700, client_uid, client_gid);
+       amfree(d);
+    }
+
+#if defined(AMANDA_DBGDIR)
+    if (chdir(AMANDA_DBGDIR) != -1
+       && stat(".", &sbuf) != -1
+       && (sbuf.st_mode & 0777) == 0700        /* drwx------ */
+       && sbuf.st_uid == client_uid) {         /* owned by Amanda user */
+       cd_ok = 1;                              /* this is a good place to be */
+    }
+#endif
+    if (! cd_ok
+       && chdir(AMANDA_TMPDIR) != -1
+       && stat(".", &sbuf) != -1
+       && (sbuf.st_mode & 0777) == 0700        /* drwx------ */
+       && sbuf.st_uid == client_uid) {         /* owned by Amanda user */
+       cd_ok = 1;                              /* this is a good place to be */
+    }
+    if(cd_ok) {
+       save_core();                            /* save any old core file */
+    } else {
+       (void) chdir("/");                      /* assume this works */
+    }
+}
+
+/*
+ *=====================================================================
+ * Save an existing core file.
+ *
+ * void save_core (void)
+ *
+ * entry:      none
+ * exit:       none
+ *
+ * Renames:
+ *
+ *     "core"          to "coreYYYYMMDD",
+ *     "coreYYYYMMDD"  to "coreYYYYMMDDa",
+ *     "coreYYYYMMDDa" to "coreYYYYMMDDb",
+ *     ...
+ *
+ * ... where YYYYMMDD is the modification time of the original file.
+ * If it gets that far, an old "coreYYYYMMDDz" is thrown away.
+ *=====================================================================
+ */
+
+void
+save_core()
+{
+    struct stat sbuf;
+
+    if(stat("core", &sbuf) != -1) {
+        char *ts;
+        char suffix[2];
+        char *old, *new;
+
+       ts = construct_datestamp((time_t *)&sbuf.st_mtime);
+        suffix[0] = 'z';
+        suffix[1] = '\0';
+        old = vstralloc("core", ts, suffix, NULL);
+        new = NULL;
+        while(ts[0] != '\0') {
+            amfree(new);
+            new = old;
+            if(suffix[0] == 'a') {
+                suffix[0] = '\0';
+            } else if(suffix[0] == '\0') {
+                ts[0] = '\0';
+            } else {
+                suffix[0]--;
+            }
+            old = vstralloc("core", ts, suffix, NULL);
+            (void)rename(old, new);         /* it either works ... */
+        }
+       amfree(ts);
+        amfree(old);
+        amfree(new);
+    }
+}
+
+/*
+** Sanitise a file name.
+** 
+** Convert all funny 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.
+*/
+char *sanitise_filename(inp)
+char *inp;
+{
+    char *buf;
+    int buf_size;
+    char *s, *d;
+    int ch;
+
+    buf_size = 2 * strlen(inp) + 1;            /* worst case */
+    buf = alloc(buf_size);
+    d = buf;
+    s = inp;
+    while((ch = *s++) != '\0') {
+       if(ch == '_') {
+           if(d >= buf + buf_size) {
+               return NULL;                    /* cannot happen */
+           }
+           *d++ = '_';                         /* convert _ to __ to try */
+                                               /* and ensure unique output */
+       } else if(ch == '/' || isspace(ch)) {
+           ch = '_';   /* convert "bad" to "_" */
+       }
+       if(d >= buf + buf_size) {
+           return NULL;                        /* cannot happen */
+       }
+       *d++ = ch;
+    }
+    if(d >= buf + buf_size) {
+       return NULL;                            /* cannot happen */
+    }
+    *d = '\0';
+
+    return buf;
+}
+
+/*
+ *=====================================================================
+ * Get the next line of input from a stdio file.
+ *
+ * char *agets (FILE *f)
+ *
+ * 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).
+ *
+ * Notes:      the newline, if read, is removed from the string
+ *             the caller is responsible for free'ing the string
+ *=====================================================================
+ */
+
+char *
+debug_agets(s, l, file)
+    char *s;
+    int l;
+    FILE *file;
+{
+    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));
+
+#define        AGETS_LINE_INCR 128
+
+    line_size = AGETS_LINE_INCR;
+    line = debug_alloc (s, l, line_size);
+    line_free = line_size;
+    line_ptr = line;
+    line_len = 0;
+
+    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;
+       }
+       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 */
+    }
+    /*
+     * 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 (char *file, int line, int fd)
+ *
+ * entry:      file, line = caller source location
+ *             fd = file descriptor to look up
+ * exit:       returns a pointer to the buffer, possibly new
+ *=====================================================================
+ */
+
+static struct areads_buffer {
+    char *buffer;
+    char *endptr;
+    ssize_t bufsize;
+} *areads_buffer = NULL;
+static int areads_bufcount = 0;
+static ssize_t areads_bufsize = BUFSIZ;                /* for the test program */
+
+static void
+areads_getbuf(s, l, fd)
+    char *s;
+    int l;
+    int fd;
+{
+    struct areads_buffer *new;
+    ssize_t size;
+
+    assert(fd >= 0);
+    if(fd >= areads_bufcount) {
+       size = (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);
+           memcpy(new, areads_buffer, size);
+       }
+       amfree(areads_buffer);
+       areads_buffer = new;
+       areads_bufcount = fd + 1;
+    }
+    if(areads_buffer[fd].buffer == NULL) {
+       areads_buffer[fd].bufsize = areads_bufsize;
+       areads_buffer[fd].buffer = debug_alloc(s, l,
+                                              areads_buffer[fd].bufsize + 1);
+       areads_buffer[fd].buffer[0] = '\0';
+       areads_buffer[fd].endptr = areads_buffer[fd].buffer;
+    }
+}
+
+/*
+ *=====================================================================
+ * Return the amount of data still in an areads buffer.
+ *
+ * ssize_t areads_dataready (int fd)
+ *
+ * entry:      fd = file descriptor to release buffer for
+ * exit:       returns number of bytes of data ready to process
+ *=====================================================================
+ */
+
+ssize_t
+areads_dataready(fd)
+    int fd;
+{
+    ssize_t r = 0;
+
+    if(fd >= 0 && fd < areads_bufcount && areads_buffer[fd].buffer != NULL) {
+       r = (ssize_t) (areads_buffer[fd].endptr - areads_buffer[fd].buffer);
+    }
+    return r;
+}
+
+/*
+ *=====================================================================
+ * Release a buffer for a particular file descriptor used by areads().
+ *
+ * void areads_relbuf (int fd)
+ *
+ * entry:      fd = file descriptor to release buffer for
+ * exit:       none
+ *=====================================================================
+ */
+
+void
+areads_relbuf(fd)
+    int fd;
+{
+    if(fd >= 0 && fd < areads_bufcount) {
+       amfree(areads_buffer[fd].buffer);
+       areads_buffer[fd].endptr = NULL;
+       areads_buffer[fd].bufsize = 0;
+    }
+}
+
+/*
+ *=====================================================================
+ * Get the next line of input from a file descriptor.
+ *
+ * char *areads (int fd)
+ *
+ * entry:      fd = file descriptor to read
+ * exit:       returns a pointer to an alloc'd string or NULL at EOF
+ *             or error (errno will be zero on EOF).
+ *
+ * Notes:      the newline, if read, is removed from the string
+ *             the caller is responsible for free'ing the string
+ *=====================================================================
+ */
+
+char *
+debug_areads (s, l, fd)
+    char *s;
+    int l;
+    int fd;
+{
+    char *nl;
+    char *line;
+    char *buffer;
+    char *endptr;
+    char *newbuf;
+    ssize_t buflen;
+    ssize_t size;
+    ssize_t r;
+
+    malloc_enter(dbmalloc_caller_loc(s, l));
+
+    if(fd < 0) {
+       errno = EBADF;
+       return NULL;
+    }
+    areads_getbuf(s, l, fd);
+    buffer = areads_buffer[fd].buffer;
+    endptr = areads_buffer[fd].endptr;
+    buflen = areads_buffer[fd].bufsize - (endptr - buffer);
+    while((nl = strchr(buffer, '\n')) == NULL) {
+       /*
+        * No newline yet, so get more data.
+        */
+       if (buflen == 0) {
+           if ((size = areads_buffer[fd].bufsize) < 256 * areads_bufsize) {
+               size *= 2;
+           } else {
+               size += 256 * areads_bufsize;
+           }
+           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);
+       }
+       if ((r = read(fd, endptr, buflen)) <= 0) {
+           if(r == 0) {
+               errno = 0;              /* flag EOF instead of error */
+           }
+           malloc_leave(dbmalloc_caller_loc(s, l));
+           return NULL;
+       }
+       endptr[r] = '\0';               /* we always leave room for this */
+       endptr += r;
+       buflen -= r;
+    }
+    *nl++ = '\0';
+    line = stralloc(buffer);
+    size = endptr - nl;                        /* data still left in buffer */
+    memmove(buffer, nl, size);
+    areads_buffer[fd].endptr = buffer + size;
+    areads_buffer[fd].endptr[0] = '\0';
+    malloc_leave(dbmalloc_caller_loc(s, l));
+    return line;
+}
+
+#ifdef TEST
+
+int main(argc, argv)
+       int argc;
+       char **argv;
+{
+       int rc;
+       int fd;
+       char *name;
+       char *top;
+       char *file;
+       char *line;
+
+       for(fd = 3; fd < 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
+                * descriptor, which in turn might be used as an index into
+                * an array (e.g. an fd_set).
+                */
+               close(fd);
+       }
+
+       set_pname("file test");
+
+       name = "/tmp/a/b/c/d/e";
+       if (argc > 2 && argv[1][0] != '\0') {
+               name = argv[1];
+       }
+       top = "/tmp";
+       if (argc > 3 && argv[2][0] != '\0') {
+               name = argv[2];
+       }
+       file = "/etc/hosts";
+       if (argc > 4 && argv[3][0] != '\0') {
+               name = argv[3];
+       }
+
+       fprintf(stderr, "Create parent directories of %s ...", name);
+       rc = mkpdir(name, 02777, (uid_t)-1, (gid_t)-1);
+       if (rc == 0)
+               fprintf(stderr, " done\n");
+       else {
+               perror("failed");
+               return rc;
+       }
+
+       fprintf(stderr, "Delete %s back to %s ...", name, top);
+       rc = rmpdir(name, top);
+       if (rc == 0)
+               fprintf(stderr, " done\n");
+       else {
+               perror("failed");
+               return rc;
+       }
+
+       fprintf(stderr, "areads dump of %s ...", file);
+       if ((fd = open (file, 0)) < 0) {
+               perror(file);
+               return 1;
+       }
+       areads_bufsize = 1;                     /* force buffer overflow */
+       while ((line = areads(fd)) != NULL) {
+               puts(line);
+               amfree(line);
+       }
+       aclose(fd);
+       fprintf(stderr, " done.\n");
+
+       fprintf(stderr, "Finished.\n");
+       return 0;
+}
+
+#endif
diff --git a/common-src/fileheader.c b/common-src/fileheader.c
new file mode 100644 (file)
index 0000000..928a37c
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * 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: fileheader.c,v 1.11.4.1.4.1.2.6 2003/10/24 13:44:49 martinea Exp $
+ *
+ */
+
+#include "amanda.h"
+#include "fileheader.h"
+
+
+void fh_init(file)
+dumpfile_t *file;
+{
+    memset(file,'\0',sizeof(*file));
+    file->blocksize = DISK_BLOCK_BYTES;
+}
+
+
+void
+parse_file_header(buffer, file, buflen)
+    char *buffer;
+    dumpfile_t *file;
+    size_t buflen;
+{
+    string_t line, save_line;
+    char *bp, *str, *ptr_buf, *start_buf;
+    int nchars;
+    char *verify;
+    char *s, *s1, *s2;
+    int ch;
+    int done;
+
+    /* isolate first line */
+
+    nchars = buflen<sizeof(line)? buflen : sizeof(line) - 1;
+    for(s=line, ptr_buf=buffer; ptr_buf < buffer+nchars; ptr_buf++, s++) {
+       ch = *ptr_buf;
+       if(ch == '\n') {
+           *s = '\0';
+           break;
+       }
+       *s = ch;
+    }
+    line[sizeof(line)-1] = '\0';
+    strncpy(save_line, line, sizeof(save_line));
+
+    fh_init(file); 
+    s = line;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    str = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    if(strcmp(str, "NETDUMP:") != 0 && strcmp(str,"AMANDA:") != 0) {
+       file->type = F_UNKNOWN;
+       return;
+    }
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       goto weird_header;
+    }
+    str = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    if(strcmp(str, "TAPESTART") == 0) {
+       file->type = F_TAPESTART;
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       verify = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       if(strcmp(verify, "DATE") != 0) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->datestamp, sizeof(file->datestamp), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       verify = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       if(strcmp(verify, "TAPE") != 0) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->name, sizeof(file->name), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+    } else if(strcmp(str, "FILE") == 0 || 
+             strcmp(str, "CONT_FILE") == 0) {
+       if(strcmp(str, "FILE") == 0)
+           file->type = F_DUMPFILE;
+       else if(strcmp(str, "CONT_FILE") == 0)
+           file->type = F_CONT_DUMPFILE;
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->datestamp, sizeof(file->datestamp), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->name, sizeof(file->name), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->disk, sizeof(file->disk), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       verify = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       if(strcmp(verify, "lev") != 0) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%d", &file->dumplevel) != 1) {
+           goto weird_header;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       verify = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       if(strcmp(verify, "comp") != 0) {
+           goto weird_header;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->comp_suffix, sizeof(file->comp_suffix), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+
+       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);
+           file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           return;                             /* "program" is optional */
+       }
+       verify = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       if(strcmp(verify, "program") != 0) {
+           return;                             /* "program" is optional */
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->program, sizeof(file->program), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+
+       if(file->program[0]=='\0') {
+           strncpy(file->program, "RESTORE", sizeof(file->program)-1);
+           file->program[sizeof(file->program)-1] = '\0';
+       }
+
+    } else if(strcmp(str, "TAPEEND") == 0) {
+       file->type = F_TAPEEND;
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       verify = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       if(strcmp(verify, "DATE") != 0) {
+           return;                             /* "program" is optional */
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           goto weird_header;
+       }
+       copy_string(s, ch, file->datestamp, sizeof(file->datestamp), bp);
+       if(bp == NULL) {
+           goto weird_header;
+       }
+    } else {
+       goto weird_header;
+    }
+
+    done=0;
+    do {
+       /* isolate the next line */
+       int max_char;
+       ptr_buf++;
+       start_buf = ptr_buf;
+       max_char = buflen - (ptr_buf - buffer);
+       nchars = max_char<sizeof(line)? max_char : sizeof(line) - 1;
+       for(s=line ; ptr_buf < start_buf+nchars; ptr_buf++, s++) {
+           ch = *ptr_buf;
+           if(ch == '\n') {
+               *s = '\0';
+               break;
+           }
+           else if(ch == '\0' || ch == '\014') {
+               done=1;
+               break;
+           }
+           *s = ch;
+       }
+       if (done == 1) break;
+       if(ptr_buf >= start_buf+nchars) done = 1;
+       line[sizeof(line)-1] = '\0';
+       s = line;
+       ch = *s++;
+#define SC "CONT_FILENAME="
+       if(strncmp(line,SC,strlen(SC)) == 0) {
+           s = line + strlen(SC);
+           ch = *s++;
+           copy_string(s, ch, file->cont_filename, 
+                       sizeof(file->cont_filename), bp);
+       }
+#undef SC
+#define SC "PARTIAL="
+       else if(strncmp(line,SC,strlen(SC)) == 0) {
+           s = line + strlen(SC);
+           if(strncmp(s,"yes",3)==0 || strncmp(s,"YES",3)==0)
+               file->is_partial=1;
+           ch = *s++;
+       }
+#undef SC
+#define SC "To restore, position tape at start of file and run:"
+       else if(strncmp(line,SC,strlen(SC)) == 0) {
+       }
+#undef SC
+#define SC "\tdd if=<tape> bs="
+       else if(strncmp(line,SC,strlen(SC)) == 0) {
+           s = strtok(line, "|");
+           s1 = strtok(NULL, "|");
+           s2 = strtok(NULL, "|");
+           if(!s1) {
+               strncpy(file->recover_cmd,"BUG",sizeof(file->recover_cmd));
+               file->recover_cmd[sizeof(file->recover_cmd)-1] = '\0';
+           }
+           else if(!s2) {
+               strncpy(file->recover_cmd,s1+1,sizeof(file->recover_cmd));
+               file->recover_cmd[sizeof(file->recover_cmd)-1] = '\0';
+           }
+           else {
+               strncpy(file->uncompress_cmd,s1, sizeof(file->uncompress_cmd));
+               file->uncompress_cmd[sizeof(file->uncompress_cmd)-2] = '\0';
+               strcat(file->uncompress_cmd,"|");
+               strncpy(file->recover_cmd,s2+1,sizeof(file->recover_cmd));
+               file->recover_cmd[sizeof(file->recover_cmd)-1] = '\0';
+           }
+       }
+#undef SC
+       else { /* ignore unknown line */
+       }
+    } while(!done);
+
+    return;
+
+ weird_header:
+
+    fprintf(stderr, "%s: strange amanda header: \"%s\"\n", get_pname(), save_line);
+    file->type = F_WEIRD;
+    return;
+}
+
+
+void
+build_header(buffer, file, buflen)
+    char *buffer;
+    dumpfile_t *file;
+    size_t buflen;
+{
+    char *line = NULL;
+    char number[NUM_STR_SIZE*2];
+
+    memset(buffer,'\0',buflen);
+
+    switch (file->type) {
+    case F_TAPESTART: ap_snprintf(buffer, buflen,
+                                 "AMANDA: TAPESTART DATE %s TAPE %s\n\014\n",
+                                 file->datestamp, file->name);
+                     break;
+    case F_CONT_DUMPFILE:
+    case F_DUMPFILE : if( file->type == F_DUMPFILE) {
+                       ap_snprintf(buffer, buflen,
+                                 "AMANDA: FILE %s %s %s lev %d comp %s program %s\n",
+                                 file->datestamp, file->name, file->disk,
+                                 file->dumplevel, file->comp_suffix,
+                                 file->program);
+                     }
+                     else if( file->type == F_CONT_DUMPFILE) {
+                       ap_snprintf(buffer, buflen,
+                                 "AMANDA: CONT_FILE %s %s %s lev %d comp %s program %s\n",
+                                 file->datestamp, file->name, file->disk,
+                                 file->dumplevel, file->comp_suffix,
+                                 file->program);
+                     }
+                     buffer[buflen-1] = '\0';
+                     if(strlen(file->cont_filename) != 0) {
+                       line = newvstralloc(line, "CONT_FILENAME=",
+                                           file->cont_filename, "\n", NULL);
+                       strncat(buffer,line,buflen-strlen(buffer));
+                     }
+                     if(file->is_partial != 0) {
+                       strncat(buffer,"PARTIAL=YES\n",buflen-strlen(buffer));
+                     }
+                     strncat(buffer,
+                       "To restore, position tape at start of file and run:\n",
+                       buflen-strlen(buffer));
+                     ap_snprintf(number, sizeof(number),
+                                 "%ld", file->blocksize / 1024);
+                     line = newvstralloc(line, "\t",
+                                      "dd",
+                                      " if=<tape>",
+                                      " bs=", number, "k",
+                                      " skip=1",
+                                      " |", file->uncompress_cmd,
+                                      " ", file->recover_cmd,
+                                      "\n",
+                                      "\014\n",        /* ?? */
+                                      NULL);
+                     strncat(buffer, line, buflen-strlen(buffer));
+                     amfree(line);
+                     buffer[buflen-1] = '\0';
+                     break;
+    case F_TAPEEND  : ap_snprintf(buffer, buflen,
+                                 "AMANDA: TAPEEND DATE %s\n\014\n",
+                                 file->datestamp);
+                     break;
+    case F_UNKNOWN  : break;
+    case F_WEIRD    : break;
+    }
+}
+
+
+void print_header(outf, file)
+FILE *outf;
+dumpfile_t *file;
+/*
+ * Prints the contents of the file structure.
+ */
+{
+    switch(file->type) {
+    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:
+       fprintf(outf, "dumpfile: date %s host %s disk %s lev %d comp %s",
+               file->datestamp, file->name, file->disk, file->dumplevel, 
+               file->comp_suffix);
+       if(*file->program)
+           fprintf(outf, " program %s\n",file->program);
+       else
+           fprintf(outf, "\n");
+       break;
+    case F_CONT_DUMPFILE:
+       fprintf(outf, "cont dumpfile: date %s host %s disk %s lev %d comp %s",
+               file->datestamp, file->name, file->disk, file->dumplevel, 
+               file->comp_suffix);
+       if(*file->program)
+           fprintf(outf, " program %s\n",file->program);
+       else
+           fprintf(outf, "\n");
+       break;
+    case F_TAPEEND:
+       fprintf(outf, "end of tape: date %s\n", file->datestamp);
+       break;
+    }
+}
+
+
+int known_compress_type(file)
+dumpfile_t *file;
+{
+    if(strcmp(file->comp_suffix, ".Z") == 0)
+       return 1;
+#ifdef HAVE_GZIP
+    if(strcmp(file->comp_suffix, ".gz") == 0)
+       return 1;
+#endif
+    return 0;
+}
diff --git a/common-src/fileheader.h b/common-src/fileheader.h
new file mode 100644 (file)
index 0000000..7666a0f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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: fileheader.h,v 1.6.4.1.4.1.2.2 2002/02/11 01:30:42 jrjackson Exp $
+ *
+ */
+
+#ifndef FILEHEADER_H
+#define FILEHEADER_H
+
+#include "amanda.h"
+
+#define STRMAX         256
+
+typedef char string_t[STRMAX];
+typedef enum {
+    F_UNKNOWN, F_WEIRD, F_TAPESTART, F_TAPEEND, 
+    F_DUMPFILE, F_CONT_DUMPFILE
+} filetype_t;
+
+typedef struct file_s {
+    filetype_t type;
+    string_t datestamp;
+    int dumplevel;
+    int compressed;
+    string_t comp_suffix;
+    string_t name;     /* hostname or label */
+    string_t disk;
+    string_t program;
+    string_t recover_cmd;
+    string_t uncompress_cmd;
+    string_t cont_filename;
+    int is_partial;
+    long blocksize;
+} dumpfile_t;
+
+/* local functions */
+
+void  fh_init             P((dumpfile_t *file));
+void  parse_file_header   P((char *buffer, dumpfile_t *file, size_t buflen));
+void  build_header        P((char *buffer,
+                            dumpfile_t *file,
+                            size_t buflen));
+void  print_header        P((FILE *outf, dumpfile_t *file));
+int   known_compress_type P((dumpfile_t *file));
+
+#endif /* !FILEHEADER_H */
diff --git a/common-src/genversion.c b/common-src/genversion.c
new file mode 100644 (file)
index 0000000..65bc6f9
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+ * 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: genversion.c,v 1.18.4.4.4.1.2.2 2003/10/07 17:10:08 martinea Exp $
+ *
+ * dump the current Amanda version info
+ */
+#include "amanda.h"
+#include "version.h"
+#include "genversion.h"
+
+int main P((void));
+
+#define MARGIN         70
+
+#define newline() do {                                                 \
+    printf("  \"%s\\n\",\n", line);                                    \
+    *line = '\0';                                                      \
+    linelen = 0;                                                       \
+} while (0)
+
+/* Print a string */
+#define prstr(string) do {                                             \
+    int len = strlen(string);                                          \
+    if(linelen+len >= MARGIN) {                                        \
+       newline();                                                      \
+       ap_snprintf(line, sizeof(line), "%*s", indent, "");             \
+       linelen = indent;                                               \
+    }                                                                  \
+    line[sizeof(line)-1] = '\0';                                       \
+    strncat(line, (string), sizeof(line)-strlen(line));                        \
+    linelen += len;                                                    \
+} while (0)
+
+/* Print a text "variable" */
+#define prvar(var, val) do {                                           \
+    str = newvstralloc(str, (var), "=\\\"", (val), "\\\"", NULL);      \
+    prstr(str);                                                                \
+} while(0)
+
+/* Print a undef "variable" */
+#define prundefvar(var) do {                                           \
+    str = newvstralloc(str, (var), "=UNDEF", NULL);                    \
+    prstr(str);                                                                \
+} while(0)
+
+/* Print a numeric "variable" */
+#define prnum(var, val) do {                                           \
+    char number[NUM_STR_SIZE];                                         \
+    ap_snprintf(number, sizeof(number), "%ld", (long)(val));           \
+    str = newvstralloc(str, (var), "=", number, NULL);                 \
+    prstr(str);                                                                \
+} while(0)
+
+int main()
+{
+    char line[STR_SIZE], *str = NULL;
+    int  linelen, indent;
+    int fd;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("genversion");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    printf("/* version.c - generated by genversion.c - DO NOT EDIT! */\n");
+    printf("char *version_info[] = {\n");
+
+    *line = '\0', linelen = 0, indent = 0;
+
+
+    prstr("build:"); indent = linelen;
+
+    {
+       char version_str[STR_SIZE];
+
+       ap_snprintf(version_str, sizeof(version_str), "Amanda-%s", version());
+       prvar(" VERSION", version_str);
+    }
+
+#ifdef BUILT_DATE
+    prvar(" BUILT_DATE", BUILT_DATE);
+#else
+    prundefvar(" BUILT_DATE");
+#endif
+
+#ifdef BUILT_MACH
+    prvar(" BUILT_MACH", BUILT_MACH);
+#else
+    prundefvar(" BUILT_MACH");
+#endif
+
+#ifdef CC
+    prvar(" CC", CC);
+#else
+    prundefvar(" CC");
+#endif
+
+#ifdef CONFIGURE_COMMAND
+    prvar(" CONFIGURE_COMMAND", CONFIGURE_COMMAND);
+#else
+    prundefvar(" CONFIGURE_COMMAND");
+#endif
+
+    newline();
+
+
+    prstr("paths:"); indent = linelen;
+
+    prvar(" bindir", bindir);
+    prvar(" sbindir", sbindir);
+    prvar(" libexecdir", libexecdir);
+    prvar(" mandir", mandir);
+    prvar(" AMANDA_TMPDIR", AMANDA_TMPDIR);
+#ifdef AMANDA_DBGDIR
+    prvar(" AMANDA_DBGDIR", AMANDA_DBGDIR);
+#else
+    prundefvar(" AMANDA_DBGDIR");
+#endif
+
+    prvar(" CONFIG_DIR", CONFIG_DIR);
+
+#ifdef DEV_PREFIX
+    prvar(" DEV_PREFIX", DEV_PREFIX);
+#else
+    prundefvar(" DEV_PREFIX");
+#endif
+
+#ifdef RDEV_PREFIX
+    prvar(" RDEV_PREFIX", RDEV_PREFIX);
+#else
+    prundefvar(" RDEV_PREFIX");
+#endif
+
+#ifdef DUMP
+    prvar(" DUMP", DUMP);
+    prvar(" RESTORE", RESTORE);
+#else
+    prundefvar(" DUMP");
+    prundefvar(" RESTORE");
+#endif
+
+#ifdef VDUMP
+    prvar(" VDUMP", VDUMP);
+    prvar(" VRESTORE", VRESTORE);
+#else
+    prundefvar(" VDUMP");
+    prundefvar(" VRESTORE");
+#endif
+
+#ifdef XFSDUMP
+    prvar(" XFSDUMP", XFSDUMP);
+    prvar(" XFSRESTORE", XFSRESTORE);
+#else
+    prundefvar(" XFSDUMP");
+    prundefvar(" XFSRESTORE");
+#endif
+
+#ifdef VXDUMP
+    prvar(" VXDUMP", VXDUMP);
+    prvar(" VXRESTORE", VXRESTORE);
+#else
+    prundefvar(" VXDUMP");
+    prundefvar(" VXRESTORE");
+#endif
+
+#ifdef SAMBA_CLIENT
+    prvar(" SAMBA_CLIENT", SAMBA_CLIENT);
+#else
+    prundefvar(" SAMBA_CLIENT");
+#endif
+
+#ifdef GNUTAR
+    prvar(" GNUTAR", GNUTAR);
+#else
+    prundefvar(" GNUTAR");
+#endif
+
+#ifdef COMPRESS_PATH
+    prvar(" COMPRESS_PATH", COMPRESS_PATH);
+#else
+    prundefvar(" COMPRESS_PATH");
+#endif
+
+#ifdef UNCOMPRESS_PATH
+    prvar(" UNCOMPRESS_PATH", UNCOMPRESS_PATH);
+#else
+    prundefvar(" UNCOMPRESS_PATH");
+#endif
+
+#ifdef LPRCMD
+    prvar(" LPRCMD", LPRCMD);
+#else
+    prundefvar(" LPRCMD");
+#endif
+
+    prvar(" MAILER", MAILER);
+
+#ifdef GNUTAR_LISTED_INCREMENTAL_DIR
+    prvar(" listed_incr_dir", GNUTAR_LISTED_INCREMENTAL_DIR);
+#else
+    prundefvar(" listed_incr_dir");
+#endif
+
+    newline();
+
+
+    prstr("defs: "); indent = linelen;
+
+    prvar(" DEFAULT_SERVER", DEFAULT_SERVER);
+    prvar(" DEFAULT_CONFIG", DEFAULT_CONFIG);
+    prvar(" DEFAULT_TAPE_SERVER", DEFAULT_TAPE_SERVER);
+    prvar(" DEFAULT_TAPE_DEVICE", DEFAULT_TAPE_DEVICE);
+
+#ifdef AIX_BACKUP
+    prstr(" AIX_BACKUP");
+#endif
+
+#ifdef AIX_TAPEIO
+    prstr(" AIX_TAPEIO");
+#endif
+
+#ifdef BROKEN_VOID
+    prstr(" BROKEN_VOID");
+#endif
+
+#ifdef DUMP_RETURNS_1
+    prstr(" DUMP_RETURNS_1");
+#endif
+
+#ifdef HAVE_MMAP
+    prstr(" HAVE_MMAP");
+#endif
+
+#ifndef HAVE_STRERROR
+    prstr(" NEED_STRERROR");
+#endif
+
+#ifndef HAVE_STRSTR
+    prstr(" NEED_STRSTR");
+#endif
+
+#ifdef HAVE_SYSVSHM
+    prstr(" HAVE_SYSVSHM");
+#endif
+
+#ifdef USE_POSIX_FCNTL
+    prstr(" LOCKING=POSIX_FCNTL");
+#endif
+#ifdef USE_FLOCK
+    prstr(" LOCKING=FLOCK");
+#endif
+#ifdef USE_LOCKF
+    prstr(" LOCKING=LOCKF");
+#endif
+#ifdef USE_LNLOCK
+    prstr(" LOCKING=LNLOCK");
+#endif
+#if !defined(USE_POSIX_FCNTL) && !defined(USE_FLOCK) && !defined(USE_LOCK) && !defined(USE_LNLOCK)
+    prstr(" LOCKING=**NONE**");
+#endif
+
+#ifdef STATFS_BSD
+    prstr(" STATFS_BSD");
+#endif
+
+#ifdef STATFS_OSF1
+    prstr(" STATFS_OSF1");
+#endif
+
+#ifdef STATFS_ULTRIX
+    prstr(" STATFS_ULTRIX");
+#endif
+
+#ifdef SETPGRP_VOID
+    prstr(" SETPGRP_VOID");
+#endif
+
+#ifdef ASSERTIONS
+    prstr(" ASSERTIONS");
+#endif
+
+#ifdef DEBUG_CODE
+    prstr(" DEBUG_CODE");
+#endif
+
+#ifdef AMANDA_DEBUG_DAYS
+    prnum(" AMANDA_DEBUG_DAYS", AMANDA_DEBUG_DAYS);
+#endif
+
+#ifdef BSD_SECURITY
+    prstr(" BSD_SECURITY");
+#endif
+
+#ifdef USE_AMANDAHOSTS
+    prstr(" USE_AMANDAHOSTS");
+#endif
+
+#ifdef USE_RUNDUMP
+    prstr(" USE_RUNDUMP");
+#endif
+
+#ifdef KRB4_SECURITY
+#define HOSTNAME_INSTANCE "<hostname>"
+    {
+       char lifetime_str[NUM_STR_SIZE];
+
+       prstr(" KRB4_SECURITY");
+       prvar(" SERVER_HOST_PRINCIPLE", SERVER_HOST_PRINCIPLE);
+       prvar(" SERVER_HOST_INSTANCE", SERVER_HOST_INSTANCE);
+       prvar(" SERVER_HOST_KEY_FILE", SERVER_HOST_KEY_FILE);
+       prvar(" CLIENT_HOST_PRINCIPLE", CLIENT_HOST_PRINCIPLE);
+       prvar(" CLIENT_HOST_INSTANCE", CLIENT_HOST_INSTANCE);
+       prvar(" CLIENT_HOST_KEY_FILE", CLIENT_HOST_KEY_FILE);
+       ap_snprintf(lifetime_str, sizeof(lifetime_str), "%d", TICKET_LIFETIME);
+       prvar(" TICKET_LIFETIME", lifetime_str);
+    }
+#endif
+
+    prvar(" CLIENT_LOGIN", CLIENT_LOGIN);
+
+#ifdef FORCE_USERID
+    prstr(" FORCE_USERID");
+#endif
+
+#ifdef USE_VERSION_SUFFIXES
+    prstr(" USE_VERSION_SUFFIXES");
+#endif
+
+#ifdef HAVE_GZIP
+    prstr(" HAVE_GZIP");
+#endif
+
+#ifdef COMPRESS_SUFFIX
+    prvar(" COMPRESS_SUFFIX", COMPRESS_SUFFIX);
+#endif
+
+#ifdef COMPRESS_FAST_OPT
+    prvar(" COMPRESS_FAST_OPT", COMPRESS_FAST_OPT);
+#endif
+
+#ifdef COMPRESS_BEST_OPT
+    prvar(" COMPRESS_BEST_OPT", COMPRESS_BEST_OPT);
+#endif
+
+#ifdef UNCOMPRESS_OPT
+    prvar(" UNCOMPRESS_OPT", UNCOMPRESS_OPT);
+#endif
+
+    newline();
+
+
+    printf("  0\n};\n");
+
+    amfree(str);
+
+    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 0;
+}
diff --git a/common-src/getcwd.c b/common-src/getcwd.c
new file mode 100644 (file)
index 0000000..93e52f8
--- /dev/null
@@ -0,0 +1,67 @@
+/* 
+ * getcwd.c --
+ *
+ *     This file provides an implementation of the getcwd procedure
+ *     that uses getwd, for systems with getwd but without getcwd.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+/* $Id: getcwd.c,v 1.3.12.1 2002/02/11 01:30:42 jrjackson Exp $ */
+
+#ifndef lint
+static char rcsid[] = "$Header: /cvsroot/amanda/amanda/common-src/getcwd.c,v 1.3.12.1 2002/02/11 01:30:42 jrjackson Exp $ SPRITE (Berkeley)";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/param.h>
+
+extern char *getwd();
+extern int errno;
+
+char *
+getcwd(buf, size)
+    char *buf;                 /* Where to put path for current directory. */
+    size_t size;                       /* Number of bytes at buf. */
+{
+    char realBuffer[MAXPATHLEN+1];
+    int length;
+
+    if (getwd(realBuffer) == NULL) {
+       /*
+        * There's not much we can do besides guess at an errno to
+        * use for the result (the error message in realBuffer isn't
+        * much use...).
+        */
+
+       errno = EACCES;
+       return NULL;
+    }
+    length = strlen(realBuffer);
+    if (length >= size) {
+       errno = ERANGE;
+       return NULL;
+    }
+    strncpy(buf, realBuffer, size-1);
+    buf[size-1] = '\0';
+    return buf;
+}
diff --git a/common-src/krb4-security.c b/common-src/krb4-security.c
new file mode 100644 (file)
index 0000000..521ba71
--- /dev/null
@@ -0,0 +1,659 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1993 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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * krb4-security.c - helper functions for kerberos v4 security.
+ */
+#include "amanda.h"
+#include "krb4-security.h"
+#include "protocol.h"
+
+#define HOSTNAME_INSTANCE inst
+
+static char *ticketfilename = NULL;
+
+int krb4_auth = 0;
+int kencrypt = 0;
+des_cblock session_key;
+uint32_t auth_cksum;           /* was 'long' on 32-bit platforms */
+
+void krb4_killtickets(void)
+{
+    if(ticketfilename != NULL)
+       unlink(ticketfilename);
+    amfree(ticketfilename);
+}
+
+void kerberos_service_init()
+{
+    int rc;
+    char hostname[MAX_HOSTNAME_LENGTH+1], inst[256], realm[256];
+#if defined(HAVE_PUTENV)
+    char *tkt_env = NULL;
+#endif
+    char uid_str[NUM_STR_SIZE];
+    char pid_str[NUM_STR_SIZE];
+
+    gethostname(hostname, sizeof(hostname)-1);
+    hostname[sizeof(hostname)-1] = '\0';
+
+    if(ticketfilename == NULL)
+       atexit(krb4_killtickets);
+
+    host2krbname(hostname, inst, realm);
+
+    /*
+     * [XXX] It could be argued that if KRBTKFILE is set outside of amanda,
+     * that it's value should be used instead of us setting one up.
+     * This file also needs to be removed so that no extra tickets are
+     * hanging around.
+     */
+    ap_snprintf(uid_str, sizeof(uid_str), "%ld", (long)getuid());
+    ap_snprintf(pid_str, sizeof(pid_str), "%ld", (long)getpid());
+    ticketfilename = newvstralloc(ticketfilename,
+                                 "/tmp/tkt",
+                                 uid_str, "-", pid_str,
+                                 ".amanda",
+                                 NULL);
+    krb_set_tkt_string(ticketfilename);
+#if defined(HAVE_PUTENV)
+    tkt_env = stralloc2("KRBTKFILE=", ticketfilename);
+    putenv(tkt_env);
+    amfree(tkt_env);
+#else
+    setenv("KRBTKFILE",ticketfilename,1);
+#endif
+
+    rc = krb_get_svc_in_tkt(SERVER_HOST_PRINCIPLE, SERVER_HOST_INSTANCE,
+                           realm, "krbtgt", realm, TICKET_LIFETIME,
+                           SERVER_HOST_KEY_FILE);
+    if(rc) error("could not get krbtgt for %s.%s@%s from %s: %s",
+                SERVER_HOST_PRINCIPLE, SERVER_HOST_INSTANCE, realm,
+                SERVER_HOST_KEY_FILE, krb_err_txt[rc]);
+
+    krb_set_lifetime(TICKET_LIFETIME);
+}
+
+
+uint32_t kerberos_cksum(str)
+char *str;
+{
+    des_cblock seed;
+
+    memset(seed, 0, sizeof(seed));
+    return quad_cksum(str, NULL, strlen(str), 1, seed);
+}
+
+struct hostent *host2krbname(alias, inst, realm)
+char *alias, *inst, *realm;
+{
+    struct hostent *hp;
+    char *s, *d, *krb_realmofhost();
+    char saved_hostname[1024];
+
+    if((hp = gethostbyname(alias)) == 0) return 0;
+
+    /* get inst name: like krb_get_phost, but avoid multiple gethostbyname */
+
+    for(s = hp->h_name, d = inst; *s && *s != '.'; s++, d++)
+       *d = isupper(*s)? tolower(*s) : *s;
+    *d = '\0';
+
+    /*
+     * It isn't safe to pass hp->h_name to krb_realmofhost, since
+     * it might use gethostbyname internally.
+     */
+    bzero(saved_hostname, sizeof(saved_hostname));
+    strncpy(saved_hostname, hp->h_name, sizeof(saved_hostname)-1);
+
+    /* get realm name: krb_realmofhost always returns *something* */
+    strcpy(realm, krb_realmofhost(saved_hostname));
+
+    return hp;
+}
+
+void encrypt_data(data, length, key)
+void *data;
+int length;
+des_cblock key;
+{
+    des_key_schedule sched;
+
+    des_key_sched(key, sched);
+    des_pcbc_encrypt(data, data, length, sched, key, DES_ENCRYPT);
+}
+
+
+void decrypt_data(data, length, key)
+void *data;
+int length;
+des_cblock key;
+{
+    des_key_schedule sched;
+
+    des_key_sched(key, sched);
+    des_pcbc_encrypt(data, data, length, sched, key, DES_DECRYPT);
+}
+
+
+/*
+ * struct timeval is a host structure, and may not be used in
+ * protocols, because members are defined as 'long', rather than
+ * uint32_t.
+ */
+typedef struct net_tv {
+  int32_t tv_sec;
+  int32_t tv_usec;
+} net_tv;
+
+int kerberos_handshake(fd, key)
+int fd;
+des_cblock key;
+{
+    int rc;
+    struct timeval local;
+    net_tv localenc, remote, rcvlocal;
+    struct timezone tz;
+    char *strerror();
+    char *d;
+    int l, n, s;
+
+    /*
+     * There are two mutual authentication transactions going at once:
+     * one in which we prove the to peer that we are the legitimate
+     * party, and one in which the peer proves to us that that they
+     * are legitimate.
+     *
+     * In addition to protecting against spoofing, this exchange
+     * ensures that the two peers have the same keys, protecting
+     * against having data encrypted with one key and decrypted with
+     * another on the backup tape.
+     */
+
+    gettimeofday(&local, &tz);
+
+    /* 
+     * Convert time to  network order and sizes, encrypt,  and send to
+     * peer as the first step in  the peer proving to us that they are
+     * legitimate.
+     */
+    localenc.tv_sec = (int32_t) local.tv_sec;
+    localenc.tv_usec = (int32_t) local.tv_usec;
+    localenc.tv_sec = htonl(localenc.tv_sec);
+    localenc.tv_usec = htonl(localenc.tv_usec);
+    assert(sizeof(localenc) == 8);
+    encrypt_data(&localenc, sizeof localenc, key);
+
+    d = (char *)&localenc;
+    for(l = 0, n = sizeof(localenc); l < n; l += s) {
+       if((s = write(fd, d+l, n-l)) < 0) {
+           error("kerberos_handshake write error: [%s]", strerror(errno));
+       }
+    }
+
+    /*
+     * Read block from peer and decrypt.  This is the first step in us
+     * proving to the peer that we are legitimate.
+     */
+    d = (char *)&remote;
+    assert(sizeof(remote) == 8);
+    for(l = 0, n = sizeof(remote); l < n; l += s) {
+       if((s = read(fd, d+l, n-l)) < 0) {
+           error("kerberos_handshake read error: [%s]", strerror(errno));
+       }
+    }
+    if(l != n) {
+       error("kerberos_handshake read error: [short read]");
+    }
+
+    decrypt_data(&remote, sizeof remote, key);
+
+    /* XXX do timestamp checking here */
+
+    /*
+     * Add 1.000001 seconds to the peer's timestamp, leaving it in
+     * network order, re-encrypt and send back.
+     */
+    remote.tv_sec = ntohl(remote.tv_sec);
+    remote.tv_usec = ntohl(remote.tv_usec);
+    remote.tv_sec += 1;
+    remote.tv_usec += 1;
+    remote.tv_sec = htonl(remote.tv_sec);
+    remote.tv_usec = htonl(remote.tv_usec);
+
+    encrypt_data(&remote, sizeof remote, key);
+
+    d = (char *)&remote;
+    for(l = 0, n = sizeof(remote); l < n; l += s) {
+       if((s = write(fd, d+l, n-l)) < 0) {
+           error("kerberos_handshake write2 error: [%s]", strerror(errno));
+       }
+    }
+
+    /*
+     * Read the peers reply, decrypt, convert to host order, and
+     * verify that the peer was able to add 1.000001 seconds, thus
+     * showing that it knows the DES key.
+     */
+    d = (char *)&rcvlocal;
+    for(l = 0, n = sizeof(rcvlocal); l < n; l += s) {
+       if((s = read(fd, d+l, n-l)) < 0) {
+           error("kerberos_handshake read2 error: [%s]", strerror(errno));
+       }
+    }
+    if(l != n) {
+       error("kerberos_handshake read2 error: [short read]");
+    }
+
+    decrypt_data(&rcvlocal, sizeof rcvlocal, key);
+
+    rcvlocal.tv_sec = ntohl(rcvlocal.tv_sec);
+    rcvlocal.tv_usec = ntohl(rcvlocal.tv_usec);
+
+    dbprintf(("handshake: %d %d %d %d\n",
+             local.tv_sec, local.tv_usec,
+             rcvlocal.tv_sec, rcvlocal.tv_usec));
+
+    return (rcvlocal.tv_sec  == (int32_t) (local.tv_sec + 1)) &&
+          (rcvlocal.tv_usec == (int32_t) (local.tv_usec + 1));
+}
+
+des_cblock *host2key(hostname)
+char *hostname;
+{
+    static des_cblock key;
+    char inst[256], realm[256];
+    CREDENTIALS cred;
+
+    if(host2krbname(hostname, inst, realm))
+       krb_get_cred(CLIENT_HOST_PRINCIPLE, CLIENT_HOST_INSTANCE, realm,&cred);
+
+    memcpy(key, cred.session, sizeof key);
+    return &key;
+}
+
+int check_mutual_authenticator(key, pkt, p)
+des_cblock *key;
+pkt_t *pkt;
+proto_t *p;
+{
+    char *astr = NULL;
+    union {
+       char pad[8];
+       uint32_t i;
+    } mutual;
+    int len;
+    char *s, *fp;
+    int ch;
+
+    if(pkt->security == NULL) {
+       fprintf(stderr," pkt->security is NULL\n");
+       return 0;
+    }
+
+    s = pkt->security;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+        fprintf(stderr,"pkt->security is actually %s\n", pkt->security);
+       return 0;
+    }
+    fp = s-1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    if(strcmp(fp, "MUTUAL-AUTH") != 0) {
+       s[-1] = ch;
+        fprintf(stderr,"pkt->security is actually %s\n", pkt->security);
+       return 0;
+    }
+    s[-1] = ch;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+        fprintf(stderr,"pkt->security is actually %s\n", pkt->security);
+       return 0;
+    }
+    astr = s-1;
+    while(ch && ch != '\n') ch = *s++;
+    s[-1] = '\0';
+
+    /* XXX - goddamn it this is a worm-hole */
+    astr2bin(astr, (unsigned char *)mutual.pad, &len);
+
+    s[-1] = ch;
+
+    decrypt_data(&mutual, len, *key);
+    mutual.i = ntohl(mutual.i);
+    return mutual.i == p->auth_cksum + 1;
+}
+
+char *get_krb_security(str, host_inst, realm, cksum)
+char *str;
+char *host_inst, *realm;
+uint32_t *cksum;
+{
+    KTEXT_ST ticket;
+    int rc;
+    char inst[INST_SZ];
+
+    *cksum = kerberos_cksum(str);
+
+#if CLIENT_HOST_INSTANCE == HOSTNAME_INSTANCE
+#undef HOSTNAME_INSTANCE
+#define HOSTNAME_INSTANCE host_inst
+#endif
+
+    /*
+     * the instance must be in writable memory of size INST_SZ
+     * krb_mk_req might change it
+     */
+    strncpy(inst, CLIENT_HOST_INSTANCE, sizeof(inst) - 1);
+    inst[sizeof(inst) - 1] = '\0';
+    if((rc = krb_mk_req(&ticket, CLIENT_HOST_PRINCIPLE, inst, realm, *cksum))) {
+       if(rc == NO_TKT_FIL) {
+           /* It's been kdestroyed.  Get a new one and try again */
+           kerberos_service_init();
+           rc = krb_mk_req(&ticket, CLIENT_HOST_PRINCIPLE, 
+                           CLIENT_HOST_INSTANCE, realm, *cksum);
+       }
+       if(rc) return NULL;
+    }
+    return stralloc2("SECURITY TICKET ",
+                    bin2astr((unsigned char *)ticket.dat, ticket.length));
+}
+
+
+int krb4_security_ok(addr, str, cksum, errstr)
+struct sockaddr_in *addr;
+char *str;
+uint32_t cksum;
+char **errstr;
+{
+    KTEXT_ST ticket;
+    AUTH_DAT auth;
+    char *ticket_str, *user, inst[INST_SZ], hname[256];
+    struct passwd *pwptr;
+    int myuid, rc;
+    char *s;
+    int ch;
+
+    /* extract the ticket string from the message */
+
+    s = str;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       *errstr = newstralloc(*errstr, "[bad krb4 security line]");
+       return 0;
+    }
+#define sc "TICKET"
+    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       *errstr = newstralloc(*errstr, "[bad krb4 security line]");
+       return 0;
+    }
+    s += sizeof(sc)-1;
+    ch = s[-1];
+#undef sc
+    skip_whitespace(s, ch);
+    ticket_str = s - 1;
+    skip_line(s, ch);
+    s[-1] = '\0';
+
+    /* convert to binary ticket */
+
+    astr2bin(ticket_str, (unsigned char *)ticket.dat, &ticket.length);
+
+    /* consult kerberos server */
+
+#if CLIENT_HOST_INSTANCE == HOSTNAME_INSTANCE
+    if (gethostname(hname, sizeof(hname)) < 0) {
+       *errstr = newvstralloc(*errstr,
+           "[kerberos error: can't get hostname: ", strerror(errno), "}",
+           NULL);
+       return 0;
+    }
+#undef HOSTNAME_INSTANCE
+#define HOSTNAME_INSTANCE krb_get_phost(hname)
+#endif
+
+    /*
+     * the instance must be in writable memory of size INST_SZ
+     * krb_rd_req might change it.
+     */
+    strncpy(inst, CLIENT_HOST_INSTANCE, sizeof(inst) - 1);
+    inst[sizeof(inst) - 1] = '\0';
+    rc = krb_rd_req(&ticket, CLIENT_HOST_PRINCIPLE, inst,
+                   addr->sin_addr.s_addr, &auth, CLIENT_HOST_KEY_FILE);
+    if(rc) {
+       *errstr = newvstralloc(*errstr,
+                              "[kerberos error: ", krb_err_txt[rc], "]",
+                              NULL);
+       return 0;
+    }
+
+    /* verify checksum */
+
+    dbprintf(("msg checksum %d auth checksum %d\n", 
+             cksum, auth.checksum));
+
+    if(cksum != auth.checksum) {
+       *errstr = newstralloc(*errstr, "[kerberos error: checksum mismatch]");
+       dbprintf(("checksum error: exp %d got %d\n", 
+                 auth.checksum, cksum));
+       return 0;
+    }
+
+    /* save key/cksum for mutual auth and dump encryption */
+
+    memcpy(session_key, auth.session, sizeof(session_key));
+    auth_cksum = auth.checksum;
+
+    /* lookup our local user name */
+
+#ifdef FORCE_USERID
+    /*
+     * if FORCE_USERID is set, then we want to check the uid that we're
+     * forcing ourselves to.  Since we'll need root access to grab at the
+     * srvtab file, we're actually root, although we'll be changing into
+     * CLIENT_LOGIN once we're done the kerberos authentication.
+     */
+    if((pwptr = getpwnam(CLIENT_LOGIN)) == NULL)
+        error("error [getpwnam(%s) fails]", CLIENT_LOGIN);
+#else
+    myuid = getuid();
+    if((pwptr = getpwuid(myuid)) == NULL)
+        error("error [getpwuid(%d) fails]", myuid);
+#endif
+
+    /* check the .klogin file */
+
+    /*
+     * some implementations of kerberos will call one of the getpw()
+     * routines (getpwuid(), I think), which overwrites the value of 
+     * pwptr->pw_name if the user you want to check disagrees with
+     * who has the current uid.  (as in the case when we're still running
+     * as root, and we have FORCE_USERID set).
+     */
+    user = stralloc(pwptr->pw_name);
+
+    if(kuserok(&auth, user)) {
+       *errstr = newvstralloc(*errstr,
+                              "[",
+                              "access as ", user, " not allowed from ",
+                              auth.pname, ".", auth.pinst, "@", auth.prealm,
+                              "]", NULL);
+       dbprintf(("kuserok check failed: %s\n", *errstr));
+       amfree(user);
+       return 0;
+    }
+    amfree(user);
+
+    dbprintf(("krb4 security check passed\n"));
+    return 1;
+}
+
+/* ---------------- */
+
+/* XXX - I'm getting astrs with the high bit set in the debug output!?? */
+
+#define hex_digit(d)   ("0123456789ABCDEF"[(d)])
+#define unhex_digit(h) (((h) - '0') > 9? ((h) - 'A' + 10) : ((h) - '0'))
+
+char *bin2astr(buf, len)
+unsigned char *buf;
+int len;
+{
+    char *str, *q;
+    unsigned char *p;
+    int slen, i, needs_quote;
+
+    /* first pass, calculate string len */
+
+    slen = needs_quote = 0; p = buf;
+    if(*p == '"') needs_quote = 1;     /* special case */
+    for(i=0;i<len;i++) {
+       if(!isgraph(*p)) needs_quote = 1;
+       if(isprint(*p) && *p != '$' && *p != '"')
+           slen += 1;
+       else
+           slen += 3;
+       p++;
+    }
+    if(needs_quote) slen += 2;
+
+    /* 2nd pass, allocate string and fill it in */
+
+    str = (char *)alloc(slen+1);
+    p = buf;
+    q = str;
+    if(needs_quote) *q++ = '"';
+    for(i=0;i<len;i++) {
+       if(isprint(*p) && *p != '$' && *p != '"')
+           *q++ = *p++;
+       else {
+           *q++ = '$';
+           *q++ = hex_digit((*p >> 4) & 0xF);
+           *q++ = hex_digit(*p & 0xF);
+           p++;
+       }
+    }
+    if(needs_quote) *q++ = '"';
+    *q = '\0';
+    if(q-str != slen)
+       printf("bin2str: hmmm.... calculated %d got %d\n",
+              slen, q-str);
+    return str;
+}
+
+void astr2bin(astr, buf, lenp)
+char *astr;
+unsigned char *buf;
+int  *lenp;
+{
+    char *p;
+    unsigned char *q;
+
+    p = astr; q = buf;
+
+    if(*p != '"') {
+       /* strcpy, but without the null */
+       while(*p) *q++ = *p++;
+       *lenp = q-buf;
+       return;
+    }
+
+    p++;
+    while(*p != '"') {
+       if(*p != '$')
+           *q++ = *p++;
+       else {
+           *q++ = (unhex_digit(p[1]) << 4) + unhex_digit(p[2]);
+            p  += 3;
+       }
+    }
+    if(p-astr+1 != strlen(astr))
+       printf("astr2bin: hmmm... short inp exp %d got %d\n",
+              strlen(astr), p-astr+1);
+    *lenp = q-buf;
+}
+
+/* -------------------------- */
+/* debug routines */
+
+void
+print_hex(str,buf,len)
+char *str;
+unsigned char *buf;
+int len;
+{
+    int i;
+
+    printf("%s:", str);
+    for(i=0;i<len;i++) {
+       if(i%25 == 0) putchar('\n');
+       printf(" %02X", buf[i]);
+    }
+    putchar('\n');
+}
+
+void
+print_ticket(str, tktp)
+char *str;
+KTEXT tktp;
+{
+    int i;
+    printf("%s: length %d chk %lX\n", str, tktp->length, tktp->mbz);
+    print_hex("ticket data", tktp->dat, tktp->length);
+    fflush(stdout);
+}
+
+void
+print_auth(authp)
+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 %d\n", authp->checksum,
+          authp->life, sizeof(authp->session));
+    print_hex("session key", authp->session, sizeof(authp->session));
+    fflush(stdout);
+}
+
+void
+print_credentials(credp)
+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("ticket", credp->ticket_st.dat, credp->ticket_st.length);
+    fflush(stdout);
+}
diff --git a/common-src/krb4-security.h b/common-src/krb4-security.h
new file mode 100644 (file)
index 0000000..d56cb6b
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1993 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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * krb4-security.h - definitions for kerberos helper module
+ */
+#ifndef KRB4_SECURITY_H
+#define KRB4_SECURITY_H
+
+#include "amanda.h"
+#include "protocol.h"
+
+/* KerberosIV function prototypes (which should be in krb.h) */
+#ifdef KERBEROSIV_MISSING_PROTOTYPES /* XXX autoconf */
+char *krb_get_phost P((char *hostname));
+#endif
+
+/* Amanda krb4 function prototypes */
+void kerberos_service_init P((void));
+uint32_t kerberos_cksum P((char *str));
+struct hostent *host2krbname P((char *alias, char *inst, char *realm));
+char *bin2astr P((unsigned char *buf, int len));
+void astr2bin P((char *astr, unsigned char *buf, int  *lenp));
+void encrypt_data P((void *data, int length, des_cblock key));
+void decrypt_data P((void *data, int length, des_cblock key));
+int kerberos_handshake P((int fd, des_cblock key));
+des_cblock *host2key P((char *hostp));
+int check_mutual_authenticator P((des_cblock *key, pkt_t *pkt, proto_t *p));
+extern char *get_krb_security P((char *str,
+                                char *host_inst, char *realm,
+                                uint32_t *cksum));
+
+extern int krb4_auth;
+extern int kencrypt;
+extern des_cblock session_key;
+extern uint32_t auth_cksum;
+
+#endif
diff --git a/common-src/match.c b/common-src/match.c
new file mode 100644 (file)
index 0000000..6f94ab4
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * 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: match.c,v 1.10.4.1.4.1.2.4 2002/11/12 18:01:19 martinea Exp $
+ *
+ * functions for checking and matching regular expressions
+ */
+
+#include "amanda.h"
+#include "regex.h"
+
+char *validate_regexp(regex)
+char *regex;
+{
+    regex_t regc;
+    int result;
+    static char errmsg[STR_SIZE];
+
+    if ((result = regcomp(&regc, regex,
+                         REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
+      regerror(result, &regc, errmsg, sizeof(errmsg));
+      return errmsg;
+    }
+
+    regfree(&regc);
+
+    return NULL;
+}
+
+char *clean_regex(regex)
+char *regex;
+{
+    char *result;
+    int j;
+    size_t i;
+    result = alloc(2*strlen(regex)+1);
+
+    for(i=0,j=0;i<strlen(regex);i++) {
+       if(!isalnum((int)regex[i]))
+           result[j++]='\\';
+       result[j++]=regex[i];
+    }
+    result[j++] = '\0';
+    return result;
+}
+
+int match(regex, str)
+char *regex, *str;
+{
+    regex_t regc;
+    int result;
+    char errmsg[STR_SIZE];
+
+    if((result = regcomp(&regc, regex,
+                        REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
+        regerror(result, &regc, errmsg, sizeof(errmsg));
+       error("regex \"%s\": %s", regex, errmsg);
+    }
+
+    if((result = regexec(&regc, str, 0, 0, 0)) != 0
+       && result != REG_NOMATCH) {
+        regerror(result, &regc, errmsg, sizeof(errmsg));
+       error("regex \"%s\": %s", regex, errmsg);
+    }
+
+    regfree(&regc);
+
+    return result == 0;
+}
+
+char *validate_glob(glob)
+char *glob;
+{
+    char *regex = NULL;
+    regex_t regc;
+    int result;
+    static char errmsg[STR_SIZE];
+
+    regex = glob_to_regex(glob);
+    if ((result = regcomp(&regc, regex,
+                         REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
+      regerror(result, &regc, errmsg, sizeof(errmsg));
+      amfree(regex);
+      return errmsg;
+    }
+
+    regfree(&regc);
+    amfree(regex);
+
+    return NULL;
+}
+
+int match_glob(glob, str)
+char *glob, *str;
+{
+    char *regex = NULL;
+    regex_t regc;
+    int result;
+    char errmsg[STR_SIZE];
+
+    regex = glob_to_regex(glob);
+    if((result = regcomp(&regc, regex,
+                        REG_EXTENDED|REG_NOSUB|REG_NEWLINE)) != 0) {
+        regerror(result, &regc, errmsg, sizeof(errmsg));
+       amfree(regex);
+       error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+    }
+
+    if((result = regexec(&regc, str, 0, 0, 0)) != 0
+       && result != REG_NOMATCH) {
+        regerror(result, &regc, errmsg, sizeof(errmsg));
+       amfree(regex);
+       error("glob \"%s\" -> regex \"%s\": %s", glob, regex, errmsg);
+    }
+
+    regfree(&regc);
+    amfree(regex);
+
+    return result == 0;
+}
+
+char *glob_to_regex(glob)
+char *glob;
+{
+    char *regex;
+    char *r;
+    size_t len;
+    int ch;
+    int last_ch;
+
+    /*
+     * Allocate an area to convert into.  The worst case is a five to
+     * one expansion.
+     */
+    len = strlen(glob);
+    regex = alloc(1 + len * 5 + 1 + 1);
+
+    /*
+     * Do the conversion:
+     *
+     *  ?      -> [^/]
+     *  *      -> [^/]*
+     *  [!...] -> [^...]
+     *
+     * The following are given a leading backslash to protect them
+     * unless they already have a backslash:
+     *
+     *   ( ) { } + . ^ $ |
+     *
+     * Put a leading ^ and trailing $ around the result.  If the last
+     * non-escaped character is \ leave the $ off to cause a syntax
+     * error when the regex is compiled.
+     */
+
+    r = regex;
+    *r++ = '^';
+    last_ch = '\0';
+    for (ch = *glob++; ch != '\0'; last_ch = ch, ch = *glob++) {
+       if (last_ch == '\\') {
+           *r++ = ch;
+           ch = '\0';                  /* so last_ch != '\\' next time */
+       } else if (last_ch == '[' && ch == '!') {
+           *r++ = '^';
+       } else if (ch == '\\') {
+           *r++ = ch;
+       } else if (ch == '*' || ch == '?') {
+           *r++ = '[';
+           *r++ = '^';
+           *r++ = '/';
+           *r++ = ']';
+           if (ch == '*') {
+               *r++ = '*';
+           }
+       } else if (ch == '('
+                  || ch == ')'
+                  || ch == '{'
+                  || ch == '}'
+                  || ch == '+'
+                  || ch == '.'
+                  || ch == '^'
+                  || ch == '$'
+                  || ch == '|') {
+           *r++ = '\\';
+           *r++ = ch;
+       } else {
+           *r++ = ch;
+       }
+    }
+    if (last_ch != '\\') {
+       *r++ = '$';
+    }
+    *r = '\0';
+
+    return regex;
+}
+
+
+int match_word(glob, word, separator)
+char *glob, *word;
+char separator;
+{
+    char *regex;
+    char *r;
+    size_t  len;
+    int  ch;
+    int  last_ch;
+    int  next_ch;
+    size_t  lenword;
+    char *nword;
+    char *nglob;
+    char *g, *w;
+    int  i;
+
+    lenword = strlen(word);
+    nword = (char *)alloc(lenword + 3);
+
+    r = nword;
+    w = word;
+    if(lenword == 1 && *w == separator) {
+       *r++ = separator;
+       *r++ = separator;
+    }
+    else {
+       if(*w != separator)
+           *r++ = separator;
+       while(*w != '\0')
+           *r++ = *w++;
+       if(*(r-1) != separator)
+           *r++ = separator;    
+    }
+    *r = '\0';
+
+    /*
+     * Allocate an area to convert into.  The worst case is a six to
+     * one expansion.
+     */
+    len = strlen(glob);
+    regex = (char *)alloc(1 + len * 6 + 1 + 1 + 2 + 2);
+    r = regex;
+    nglob = stralloc(glob);
+    g = nglob;
+
+    if((len == 1 && nglob[0] == separator) ||
+       (len == 2 && nglob[0] == '^' && nglob[1] == separator) ||
+       (len == 2 && nglob[0] == separator && nglob[1] == '$') ||
+       (len == 3 && nglob[0] == '^' && nglob[1] == separator &&
+        nglob[2] == '$')) {
+       *r++ = '^';
+       *r++ = '\\';
+       *r++ = separator;
+       *r++ = '\\';
+       *r++ = separator;
+       *r++ = '$';
+    }
+    else {
+       /*
+        * Do the conversion:
+        *
+        *  ?      -> [^\separator]
+        *  *      -> [^\separator]*
+        *  [!...] -> [^...]
+        *  **     -> .*
+        *
+        * The following are given a leading backslash to protect them
+        * unless they already have a backslash:
+        *
+        *   ( ) { } + . ^ $ |
+        *
+        * If the last
+        * non-escaped character is \ leave it to cause a syntax
+        * error when the regex is compiled.
+        */
+
+       if(*g == '^') {
+           *r++ = '^';
+           *r++ = '\\';        /* escape the separator */
+           *r++ = separator;
+           g++;
+           if(*g == separator) g++;
+       }
+       else if(*g != separator) {
+           *r++ = '\\';        /* add a leading \separator */
+           *r++ = separator;
+       }
+       last_ch = '\0';
+       for (ch = *g++; ch != '\0'; last_ch = ch, ch = *g++) {
+           next_ch = *g;
+           if (last_ch == '\\') {
+               *r++ = ch;
+               ch = '\0';              /* so last_ch != '\\' next time */
+           } else if (last_ch == '[' && ch == '!') {
+               *r++ = '^';
+           } else if (ch == '\\') {
+               *r++ = ch;
+           } else if (ch == '*' || ch == '?') {
+               if(ch == '*' && next_ch == '*') {
+                   *r++ = '.';
+                   g++;
+               }
+               else {
+                   *r++ = '[';
+                   *r++ = '^';
+                   *r++ = '\\';
+                   *r++ = separator;
+                   *r++ = ']';
+               }
+               if (ch == '*') {
+                   *r++ = '*';
+               }
+           } else if (ch == '$' && next_ch == '\0') {
+               if(last_ch != separator) {
+                   *r++ = '\\';
+                   *r++ = separator;
+               }
+               *r++ = ch;
+           } else if (   ch == '('
+                      || ch == ')'
+                      || ch == '{'
+                      || ch == '}'
+                      || ch == '+'
+                      || ch == '.'
+                      || ch == '^'
+                      || ch == '$'
+                      || ch == '|') {
+               *r++ = '\\';
+               *r++ = ch;
+           } else {
+               *r++ = ch;
+           }
+       }
+       if(last_ch != '\\') {
+           if(last_ch != separator && last_ch != '$') {
+               *r++ = '\\';
+               *r++ = separator;               /* add a trailing \separator */
+           }
+       }
+    }
+    *r = '\0';
+
+    i = match(regex,nword);
+
+    amfree(nword);
+    amfree(nglob);
+    amfree(regex);
+    return i;
+}
+
+
+int match_host(glob, host)
+char *glob, *host;
+{
+    char *lglob, *lhost;
+    char *c, *d;
+    int i;
+
+    
+    lglob = (char *)alloc(strlen(glob)+1);
+    c = lglob, d=glob;
+    while( *d != '\0')
+       *c++ = tolower(*d++);
+    *c = *d;
+
+    lhost = (char *)alloc(strlen(host)+1);
+    c = lhost, d=host;
+    while( *d != '\0')
+       *c++ = tolower(*d++);
+    *c = *d;
+
+    i = match_word(lglob, lhost, '.');
+    amfree(lglob);
+    amfree(lhost);
+    return i;
+}
+
+
+int match_disk(glob, disk)
+char *glob, *disk;
+{
+    int i;
+    i = match_word(glob, disk, '/');
+    return i;
+}
+
+int match_datestamp(dateexp, datestamp)
+char *dateexp, *datestamp;
+{
+    char *dash;
+    size_t len, len_suffix;
+    int 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);
+    }
+   
+    if(dateexp[0] == '^') {
+       strncpy(mydateexp, dateexp+1, strlen(dateexp)-1); 
+       mydateexp[strlen(dateexp)-1] = '\0';
+    }
+    else {
+       strncpy(mydateexp, dateexp, strlen(dateexp));
+       mydateexp[strlen(dateexp)] = '\0';
+    }
+
+    if(mydateexp[strlen(mydateexp)] == '$') {
+       match_exact = 1;
+       mydateexp[strlen(mydateexp)] = '\0';
+    }
+    else
+       match_exact = 0;
+
+    if((dash = strchr(mydateexp,'-'))) {
+       if(match_exact == 1) {
+           error("Illegal datestamp expression %s",dateexp);
+       }
+       len = 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';
+       strncpy(lastdate, mydateexp, len_prefix);
+       strncpy(&(lastdate[len_prefix]), dash, len_suffix);
+       lastdate[len] = '\0';
+       return ((strncmp(datestamp, firstdate, strlen(firstdate)) >= 0) &&
+               (strncmp(datestamp, lastdate , strlen(lastdate))  <= 0));
+    }
+    else {
+       if(match_exact == 1) {
+           return (strcmp(datestamp, mydateexp) == 0);
+       }
+       else {
+           return (strncmp(datestamp, mydateexp, strlen(mydateexp)) == 0);
+       }
+    }
+}
diff --git a/common-src/memmove.c b/common-src/memmove.c
new file mode 100644 (file)
index 0000000..6cbd9dd
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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: memmove.c,v 1.4 1998/07/04 00:18:48 oliva Exp $
+ *
+ * wrapper file for Henry Spencer's memmove.c
+ */
+
+#include "amanda.h"
+
+#ifndef HAVE_MEMMOVE
+
+#ifdef HAVE_BCOPY
+
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+char *memmove(to, from, n)
+char *to, *from;
+size_t n;
+{
+  bcopy(from, to, n);
+  return to;
+}
+
+#else
+
+#include "../regex-src/fake/memmove.c"
+
+#endif
+
+#endif
diff --git a/common-src/mktime.c b/common-src/mktime.c
new file mode 100644 (file)
index 0000000..8aebb02
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 1987, 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Arthur David Olson of the National Cancer Institute.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * 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 $";*/
+
+/*
+ * This implementation of mktime is lifted straight from the NetBSD (BSD 4.4)
+ * version.  I modified it slightly to divorce it from the internals of the
+ * ctime library.  Thus this version can't use details of the internal
+ * timezone state file to figure out strange unnormalized struct tm values,
+ * as might result from someone doing date math on the tm struct then passing
+ * it to mktime.
+ *
+ * It just does as well as it can at normalizing the tm input, then does a
+ * binary search of the time space using the system's localtime() function.
+ *
+ * The original binary search was defective in that it didn't consider the
+ * setting of tm_isdst when comparing tm values, causing the search to be
+ * flubbed for times near the dst/standard time changeover.  The original
+ * code seems to make up for this by grubbing through the timezone info
+ * whenever the binary search barfed.  Since I don't have that luxury in
+ * portable code, I have to take care of tm_isdst in the comparison routine.
+ * This requires knowing how many minutes offset dst is from standard time.
+ *
+ * So, if you live somewhere in the world where dst is not 60 minutes offset,
+ * and your vendor doesn't supply mktime(), you'll have to edit this variable
+ * by hand.  Sorry about that.
+ */
+
+#ifndef DSTMINUTES
+#define DSTMINUTES 60
+#endif
+
+#define FALSE 0
+#define TRUE 1
+
+/* some constants from tzfile.h */
+#define SECSPERMIN      60
+#define MINSPERHOUR     60
+#define HOURSPERDAY     24
+#define DAYSPERWEEK     7
+#define DAYSPERNYEAR    365
+#define DAYSPERLYEAR    366
+#define SECSPERHOUR     (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY      ((long) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR     12
+#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 }
+};
+
+static int     year_lengths[2] = {
+       DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+/*
+** Adapted from code provided by Robert Elz, who writes:
+**     The "best" way to do mktime I think is based on an idea of Bob
+**     Kridle's (so its said...) from a long time ago. (mtxinu!kridle now).
+**     It does a binary search of the time_t space.  Since time_t's are
+**     just 32 bits, its a max of 32 iterations (even at 64 bits it
+**     would still be very reasonable).
+*/
+
+#ifndef WRONG
+#define WRONG  (-1)
+#endif /* !defined WRONG */
+
+static void
+normalize(tensptr, unitsptr, base)
+int * tensptr;
+int * unitsptr;
+int    base;
+{
+       if (*unitsptr >= base) {
+               *tensptr += *unitsptr / base;
+               *unitsptr %= base;
+       } else if (*unitsptr < 0) {
+               --*tensptr;
+               *unitsptr += base;
+               if (*unitsptr < 0) {
+                       *tensptr -= 1 + (-*unitsptr) / base;
+                       *unitsptr = base - (-*unitsptr) % base;
+               }
+       }
+}
+
+static struct tm *
+mkdst(tmp)
+struct tm *    tmp;
+{
+    /* jds */
+    static struct tm tmbuf;
+
+    tmbuf = *tmp;
+    tmbuf.tm_isdst = 1;
+    tmbuf.tm_min += DSTMINUTES;
+    normalize(&tmbuf.tm_hour, &tmbuf.tm_min, MINSPERHOUR);
+    return &tmbuf;
+}
+
+static int
+tmcomp(atmp, btmp)
+register struct tm * atmp;
+register struct tm * btmp;
+{
+       register int    result;
+
+       /* compare down to the same day */
+
+       if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
+           (result = (atmp->tm_mon - btmp->tm_mon)) == 0)
+           result = (atmp->tm_mday - btmp->tm_mday);
+
+       if(result != 0)
+           return result;
+
+       /* get rid of one-sided dst bias */
+
+       if(atmp->tm_isdst == 1 && !btmp->tm_isdst)
+           btmp = mkdst(btmp);
+       else if(btmp->tm_isdst == 1 && !atmp->tm_isdst)
+           atmp = mkdst(atmp);
+
+       /* compare the rest of the way */
+
+       if ((result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
+           (result = (atmp->tm_min - btmp->tm_min)) == 0)
+           result = atmp->tm_sec - btmp->tm_sec;
+       return result;
+}
+
+
+static time_t
+time2(tmp, okayp)
+struct tm *    tmp;
+int *          okayp;
+{
+       register int                    dir;
+       register int                    bits;
+       register int                    i;
+       register int                    saved_seconds;
+       time_t                          t;
+       struct tm                       yourtm, mytm;
+
+       *okayp = FALSE;
+       yourtm = *tmp;
+       if (yourtm.tm_sec >= SECSPERMIN + 2 || yourtm.tm_sec < 0)
+               normalize(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN);
+       normalize(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR);
+       normalize(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY);
+       normalize(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR);
+       while (yourtm.tm_mday <= 0) {
+               --yourtm.tm_year;
+               yourtm.tm_mday +=
+                       year_lengths[isleap(yourtm.tm_year + TM_YEAR_BASE)];
+       }
+       for ( ; ; ) {
+               i = mon_lengths[isleap(yourtm.tm_year +
+                       TM_YEAR_BASE)][yourtm.tm_mon];
+               if (yourtm.tm_mday <= i)
+                       break;
+               yourtm.tm_mday -= i;
+               if (++yourtm.tm_mon >= MONSPERYEAR) {
+                       yourtm.tm_mon = 0;
+                       ++yourtm.tm_year;
+               }
+       }
+       saved_seconds = yourtm.tm_sec;
+       yourtm.tm_sec = 0;
+       /*
+       ** Calculate the number of magnitude bits in a time_t
+       ** (this works regardless of whether time_t is
+       ** signed or unsigned, though lint complains if unsigned).
+       */
+       for (bits = 0, t = 1; t > 0; ++bits, t <<= 1)
+               ;
+       /*
+       ** If time_t is signed, then 0 is the median value,
+       ** if time_t is unsigned, then 1 << bits is median.
+       */
+       t = (t < 0) ? 0 : ((time_t) 1 << bits);
+       for ( ; ; ) {
+               mytm = *localtime(&t);
+               dir = tmcomp(&mytm, &yourtm);
+               if (dir != 0) {
+                       if (bits-- < 0)
+                               return WRONG;
+                       if (bits < 0)
+                               --t;
+                       else if (dir > 0)
+                               t -= (time_t) 1 << bits;
+                       else    t += (time_t) 1 << bits;
+                       continue;
+               }
+               if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
+                       break;
+
+               return WRONG;
+       }
+       t += saved_seconds;
+       *tmp = *localtime(&t);
+       *okayp = TRUE;
+       return t;
+}
+
+static time_t
+time1(tmp)
+struct tm * tmp;
+{
+       register time_t                 t;
+       int                             okay;
+
+       if (tmp->tm_isdst > 1)
+               tmp->tm_isdst = 1;
+       t = time2(tmp, &okay);
+       if (okay || tmp->tm_isdst < 0)
+               return t;
+
+       return WRONG;
+}
+
+time_t
+mktime(tmp)
+struct tm * tmp;
+{
+       return time1(tmp);
+}
diff --git a/common-src/pipespawn.c b/common-src/pipespawn.c
new file mode 100644 (file)
index 0000000..8a8af55
--- /dev/null
@@ -0,0 +1,325 @@
+#include "amanda.h"
+#include "pipespawn.h"
+#include "arglist.h"
+#include "clock.h"
+
+char skip_argument[1];
+
+#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
+{
+    va_list ap;
+    int argc;
+    char **argv;
+    int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
+    char *passwdvar = NULL;
+    int *passwdfd = NULL;
+    char number[NUM_STR_SIZE];
+    char *arg;
+    char *e;
+    int ch;
+    char **env;
+    char **newenv;
+
+    /*
+     * Log the command line and count the args.
+     */
+    dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog));
+    dbprintf(("%s: argument list:", debug_prefix(NULL)));
+    arglist_start(ap, stderrfd);
+    if ((pipedef & PASSWD_PIPE) != 0) {
+       passwdvar = arglist_val(ap, char *);
+       passwdfd = arglist_val(ap, int *);
+    }
+    argc = 0;
+    while((arg = arglist_val(ap, char *)) != NULL) {
+       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(("\""));
+       }
+    }
+    arglist_end(ap);
+    dbprintf(("\n"));
+
+    /*
+     * Create the pipes
+     */
+    if ((pipedef & STDIN_PIPE) != 0) {
+       if(pipe(inpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+    if ((pipedef & STDOUT_PIPE) != 0) {
+       if(pipe(outpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+    if ((pipedef & STDERR_PIPE) != 0) {
+       if(pipe(errpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+    if ((pipedef & PASSWD_PIPE) != 0) {
+       if(pipe(passwdpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+
+    /*
+     * Fork and set up the return or run the program.
+     */
+    switch(pid = fork()) {
+    case -1:
+       e = strerror(errno);
+       error("error [fork %s: %s]", prog, e);
+    default:   /* parent process */
+       if ((pipedef & STDIN_PIPE) != 0) {
+           aclose(inpipe[0]);          /* close input side of pipe */
+           *stdinfd = inpipe[1];
+       }
+       if ((pipedef & STDOUT_PIPE) != 0) {
+           aclose(outpipe[1]);         /* close output side of pipe */
+           *stdoutfd = outpipe[0];
+       }
+       if ((pipedef & STDERR_PIPE) != 0) {
+           aclose(errpipe[1]);         /* close output side of pipe */
+           *stderrfd = errpipe[0];
+       }
+       if ((pipedef & PASSWD_PIPE) != 0) {
+           aclose(passwdpipe[0]);      /* close input side of pipe */
+           *passwdfd = passwdpipe[1];
+       }
+       break;
+    case 0:            /* child process */
+       if ((pipedef & STDIN_PIPE) != 0) {
+           aclose(inpipe[1]);          /* close output side of pipe */
+       } else {
+           inpipe[0] = *stdinfd;
+       }
+       if ((pipedef & STDOUT_PIPE) != 0) {
+           aclose(outpipe[0]);         /* close input side of pipe */
+       } else {
+           outpipe[1] = *stdoutfd;
+       }
+       if ((pipedef & STDERR_PIPE) != 0) {
+           aclose(errpipe[0]);         /* close input side of pipe */
+       } else {
+           errpipe[1] = *stderrfd;
+       }
+       if ((pipedef & PASSWD_PIPE) != 0) {
+           aclose(passwdpipe[1]);      /* close output side of pipe */
+       }
+
+       /*
+        * Shift the pipes to the standard file descriptors as requested.
+        */
+       if(dup2(inpipe[0], 0) == -1) {
+           error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
+       }
+       if(dup2(outpipe[1], 1) == -1) {
+           error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
+       }
+       if(dup2(errpipe[1], 2) == -1) {
+           error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
+       }
+
+       /*
+        * Create the argument vector.
+        */
+       arglist_start(ap, stderrfd);
+       if ((pipedef & PASSWD_PIPE) != 0) {
+           passwdvar = arglist_val(ap, char *);
+           passwdfd = arglist_val(ap, int *);
+       }
+       argv = (char **)alloc((argc + 1) * sizeof(*argv));
+       i = 0;
+       while((argv[i] = arglist_val(ap, char *)) != NULL) {
+           if (argv[i] != skip_argument) {
+               i++;
+           }
+       }
+       arglist_end(ap);
+
+       /*
+        * Get the "safe" environment.  If we are sending a password to
+        * the child via a pipe, add the environment variable for that.
+        */
+       env = safe_env();
+       if ((pipedef & PASSWD_PIPE) != 0) {
+           for(i = 0; env[i] != NULL; i++) {}
+           newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv));
+           ap_snprintf(number, sizeof(number), "%d", passwdpipe[0]);
+           newenv[0] = vstralloc(passwdvar, "=", number, NULL);
+           for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {}
+           env = newenv;
+       }
+
+       execve(prog, argv, env);
+       e = strerror(errno);
+       error("error [exec %s: %s]", prog, e);
+       /* NOTREACHED */
+    }
+    return pid;
+}
+
+int pipespawnv(prog, pipedef, stdinfd, stdoutfd, stderrfd, my_argv)
+char *prog;
+int pipedef;
+int *stdinfd, *stdoutfd, *stderrfd;
+char **my_argv;
+{
+    int argc;
+    int pid, i, inpipe[2], outpipe[2], errpipe[2], passwdpipe[2];
+    char *passwdvar = NULL;
+    int *passwdfd = NULL;
+    char number[NUM_STR_SIZE];
+    char **arg;
+    char *e;
+    int ch;
+    char **env;
+    char **newenv;
+
+    /*
+     * Log the command line and count the args.
+     */
+    dbprintf(("%s: spawning %s in pipeline\n", debug_prefix_time(NULL), prog));
+    dbprintf(("%s: argument list:", debug_prefix(NULL)));
+    if ((pipedef & PASSWD_PIPE) != 0) {
+       passwdvar = *my_argv++;
+       passwdfd = (int *)*my_argv++;
+    }
+    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(("\""));
+       }
+    }
+    dbprintf(("\n"));
+
+    /*
+     * Create the pipes
+     */
+    if ((pipedef & STDIN_PIPE) != 0) {
+       if(pipe(inpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+    if ((pipedef & STDOUT_PIPE) != 0) {
+       if(pipe(outpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+    if ((pipedef & STDERR_PIPE) != 0) {
+       if(pipe(errpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+    if ((pipedef & PASSWD_PIPE) != 0) {
+       if(pipe(passwdpipe) == -1) {
+           error("error [open pipe to %s: %s]", prog, strerror(errno));
+       }
+    }
+
+    /*
+     * Fork and set up the return or run the program.
+     */
+    switch(pid = fork()) {
+    case -1:
+       e = strerror(errno);
+       error("error [fork %s: %s]", prog, e);
+    default:   /* parent process */
+       if ((pipedef & STDIN_PIPE) != 0) {
+           aclose(inpipe[0]);          /* close input side of pipe */
+           *stdinfd = inpipe[1];
+       }
+       if ((pipedef & STDOUT_PIPE) != 0) {
+           aclose(outpipe[1]);         /* close output side of pipe */
+           *stdoutfd = outpipe[0];
+       }
+       if ((pipedef & STDERR_PIPE) != 0) {
+           aclose(errpipe[1]);         /* close output side of pipe */
+           *stderrfd = errpipe[0];
+       }
+       if ((pipedef & PASSWD_PIPE) != 0) {
+           aclose(passwdpipe[0]);      /* close input side of pipe */
+           *passwdfd = passwdpipe[1];
+       }
+       break;
+    case 0:            /* child process */
+       if ((pipedef & STDIN_PIPE) != 0) {
+           aclose(inpipe[1]);          /* close output side of pipe */
+       } else {
+           inpipe[0] = *stdinfd;
+       }
+       if ((pipedef & STDOUT_PIPE) != 0) {
+           aclose(outpipe[0]);         /* close input side of pipe */
+       } else {
+           outpipe[1] = *stdoutfd;
+       }
+       if ((pipedef & STDERR_PIPE) != 0) {
+           aclose(errpipe[0]);         /* close input side of pipe */
+       } else {
+           errpipe[1] = *stderrfd;
+       }
+
+       /*
+        * Shift the pipes to the standard file descriptors as requested.
+        */
+       if(dup2(inpipe[0], 0) == -1) {
+           error("error [spawn %s: dup2 in: %s]", prog, strerror(errno));
+       }
+       if(dup2(outpipe[1], 1) == -1) {
+           error("error [spawn %s: dup2 out: %s]", prog, strerror(errno));
+       }
+       if(dup2(errpipe[1], 2) == -1) {
+           error("error [spawn %s: dup2 err: %s]", prog, strerror(errno));
+       }
+
+       /*
+        * Get the "safe" environment.  If we are sending a password to
+        * the child via a pipe, add the environment variable for that.
+        */
+       env = safe_env();
+       if ((pipedef & PASSWD_PIPE) != 0) {
+           for(i = 0; env[i] != NULL; i++) {}
+           newenv = (char **)alloc((i + 1 + 1) * sizeof(*newenv));
+           ap_snprintf(number, sizeof(number), "%d", passwdpipe[0]);
+           newenv[0] = vstralloc(passwdvar, "=", number, NULL);
+           for(i = 0; (newenv[i + 1] = env[i]) != NULL; i++) {}
+           env = newenv;
+       }
+
+       execve(prog, my_argv, env);
+       e = strerror(errno);
+       error("error [exec %s: %s]", prog, e);
+       /* NOTREACHED */
+    }
+    return pid;
+}
diff --git a/common-src/pipespawn.h b/common-src/pipespawn.h
new file mode 100644 (file)
index 0000000..4ef7d66
--- /dev/null
@@ -0,0 +1,23 @@
+/* Pipespawn can create up to three pipes; These defines set which pointers
+ * should have the other end assigned for a new pipe. If not set, then
+ * pipespawn will use a preexisting fd.
+ */
+#ifndef PIPESPAWN_H
+#define PIPESPAWN_H 1
+
+extern char skip_argument[1];
+
+#define STDIN_PIPE     (1 << 0)
+#define STDOUT_PIPE    (1 << 1)
+#define STDERR_PIPE    (1 << 2)
+#define PASSWD_PIPE    (1 << 3)
+
+int pipespawn P((char *prog, int pipedef,
+                int *stdinfd, int *stdoutfd, int *stderrfd,
+                ...));
+int pipespawnv P((char *prog, int pipedef,
+                 int *stdinfd, int *stdoutfd, int *stderrfd,
+                 char **my_argv));
+
+
+#endif /* PIPESPAWN_H */
diff --git a/common-src/protocol.c b/common-src/protocol.c
new file mode 100644 (file)
index 0000000..0e464ef
--- /dev/null
@@ -0,0 +1,1011 @@
+/*
+ * 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: protocol.c,v 1.27.2.1.6.3 2004/04/14 13:24:35 martinea Exp $
+ *
+ * implements amanda protocol
+ */
+#include "amanda.h"
+#include "protocol.h"
+#include "version.h"
+#ifdef KRB4_SECURITY
+#  include "krb4-security.h"
+#endif
+
+#define ACK_WAIT       10       /* time (secs) to wait for ACK - keep short */
+#define ACK_TRIES       3     /* # times we'll retry after ACK_WAIT timeout */
+#define REQ_TRIES       2   /* # times client can start over (reboot/crash) */
+
+#define DROP_DEAD_TIME (60*60)    /* If no reply in an hour, just forget it */
+
+#define MAX_HANDLES    4096
+#define OFS_DIGITS        3    /* log2(MAX_HANDLES)/4 */
+
+proto_t *pending_head = NULL;
+proto_t *pending_tail = NULL;
+int pending_qlength = 0;
+
+int proto_socket = -1;
+int proto_global_seq = 0;
+#define relseq(s) (s-proto_global_seq)
+
+proto_t **proto_handle_table;
+proto_t **proto_next_handle;
+int proto_handles;
+
+time_t proto_init_time;
+#define CURTIME        (time(0)-proto_init_time)
+
+/* local functions */
+static char *prnpstate P((pstate_t s));
+static char *prnaction P((action_t s));
+#ifdef PROTO_DEBUG
+static char *prnpktype P((pktype_t s));
+#endif
+static void pending_enqueue P((proto_t *newp));
+static proto_t *pending_dequeue P((void));
+static void pending_remove P((proto_t *p));
+static void alloc_handle P((proto_t *p));
+static void free_handle P((proto_t *p));
+static void hex P((char *str, int digits, unsigned int v));
+static int unhex P((char *str, int digits));
+static proto_t *handle2ptr P((char *str));
+static char *ptr2handle P((proto_t *p));
+static void eat_string P((dgram_t *msg, char *str));
+static int parse_integer P((dgram_t *msg));
+static char *parse_string P((dgram_t *msg));
+static char *parse_line P((dgram_t *msg));
+void parse_pkt_header P((pkt_t *pkt));
+static void setup_dgram P((proto_t *p, dgram_t *msg, 
+                          char *security, char *typestr));
+static void send_req P((proto_t *p));
+static void send_ack P((proto_t *p));
+static void send_ack_repl P((pkt_t *pkt));
+static void state_machine P((proto_t *p, action_t action, pkt_t *pkt));
+static void add_bsd_security P((proto_t *p));
+static int select_til P((time_t waketime));
+static int packet_arrived P((void));
+static void handle_incoming_packet P((void)); 
+
+
+/* -------------- */
+
+
+static char *prnpstate(s)
+pstate_t s;
+{
+    static char str[80];
+
+    switch(s) {
+    case S_BOGUS: return "S_BOGUS";
+    case S_STARTUP:  return "S_STARTUP";
+    case S_SENDREQ:  return "S_SENDREQ";
+    case S_ACKWAIT:  return "S_ACKWAIT";
+    case S_REPWAIT:  return "S_REPWAIT";
+    case S_SUCCEEDED:  return "S_SUCCEEDED";
+    case S_FAILED: return "S_FAILED";
+    default:
+       ap_snprintf(str, sizeof(str), "<bad state %d>", s);
+       return str;
+    }
+}
+
+static char *prnaction(s)
+action_t s;
+{
+    static char str[80];
+
+    switch(s) {
+    case A_BOGUS:  return "A_BOGUS";
+    case A_START:  return "A_START";
+    case A_TIMEOUT:  return "A_TIMEOUT";
+    case A_RCVDATA: return "A_RCVDATA";
+    default:
+       ap_snprintf(str, sizeof(str), "<bad action %d>", s);
+       return str;
+    }
+}
+
+#ifdef PROTO_DEBUG
+
+static char *prnpktype(s)
+pktype_t s;
+{
+    static char str[80];
+
+    switch(s) {
+    case P_BOGUS: return "P_BOGUS";
+    case P_REQ: return "P_REQ";
+    case P_REP: return "P_REP";
+    case P_ACK: return "P_ACK";
+    case P_NAK: return "P_NAK";
+    default:
+       ap_snprintf(str, sizeof(str), "<bad pktype %d>", s);
+       return str;
+    }
+}
+
+#endif
+
+
+void proto_init(socket, startseq, handles)
+int socket, startseq, handles;
+{
+    int i;
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: proto_init(socket %d, startseq %d, handles %d)\n",
+             debug_prefix_time(": protocol"),
+             socket,
+             startseq,
+             handles));
+#endif
+    if(socket < 0 || socket >= FD_SETSIZE) {
+       error("proto_init: socket %d out of range (0 .. %d)\n",
+             socket, FD_SETSIZE-1);
+    }
+    proto_socket = socket;
+    proto_global_seq = startseq;
+    proto_handles = handles;
+
+    proto_handle_table = alloc(proto_handles * sizeof(proto_t *));
+    malloc_mark(proto_handle_table);
+    proto_next_handle = proto_handle_table;
+    for(i = 0; i < proto_handles; i++)
+       proto_handle_table[i] = NULL;
+    proto_init_time = time(0);
+}
+
+
+static void pending_enqueue(newp)
+proto_t *newp;
+{
+    proto_t *curp;
+
+    /* common case shortcut: check if adding to end of list */
+
+    if(pending_tail && pending_tail->timeout <= newp->timeout)
+       curp = NULL;
+    else {
+       /* scan list for insert-sort */
+       curp = pending_head;
+       while(curp && curp->timeout <= newp->timeout)
+           curp = curp->next;
+    }
+
+    newp->next = curp;
+    if(curp) {
+       newp->prev = curp->prev;
+       curp->prev = newp;
+    }
+    else {
+       newp->prev = pending_tail;
+       pending_tail = newp;
+    }
+
+    if(newp->prev) newp->prev->next = newp;
+    else pending_head = newp;
+
+    pending_qlength++;
+}
+
+static proto_t *pending_dequeue()
+{
+    proto_t *p;
+
+    p = pending_head;
+    if(p) {
+       pending_head = p->next;
+       p->next = NULL;
+       if(pending_head) 
+           pending_head->prev = NULL;
+       else
+           pending_tail = NULL;
+       pending_qlength--;
+    }
+
+    return p;
+}
+
+static void pending_remove(p)
+proto_t *p;
+{
+    if(p->next) p->next->prev = p->prev;
+    else pending_tail = p->prev;
+
+    if(p->prev) p->prev->next = p->next;
+    else pending_head = p->next;
+
+    p->prev = p->next = NULL;
+    pending_qlength--;
+}
+
+/* -------- */
+
+#define PTR_CHARS    sizeof(proto_t *)             /* chars in a pointer */
+#define CHAR_DIGITS  2                             /* hex digits in a char */
+#define HANDLE_CHARS (OFS_DIGITS+1+PTR_CHARS*CHAR_DIGITS) /* "xxx-yyyyyyyy" */
+union handle_u {
+    unsigned char c[PTR_CHARS];
+    proto_t *p;
+} hu;
+
+static void alloc_handle(p)
+proto_t *p;
+{
+    int i;
+    proto_t **hp;
+
+    hp = proto_next_handle;
+    for(i = 0; i < proto_handles; i++) {
+       if(*hp == NULL) break;
+       hp++;
+       if(hp >= proto_handle_table + proto_handles)
+           hp = proto_handle_table;
+    }
+    if(i == proto_handles)
+       error("protocol out of handles");
+    p->handleofs = hp-proto_handle_table;
+    *hp = p;
+}
+
+static void free_handle(p)
+proto_t *p;
+{
+    if(proto_handle_table[p->handleofs] == p)
+       proto_handle_table[p->handleofs] = NULL;
+    p->handleofs = -1;
+}
+
+static void hex(str, digits, v)
+char *str;
+int digits;
+unsigned int v;
+{
+    str = str + digits - 1;
+
+    while(digits--) {
+       *str-- = "0123456789ABCDEF"[v % 16];
+       v /= 16;
+    }
+}
+
+static int unhex(str, digits)
+char *str;
+int digits;
+{
+    int d, v = 0;
+
+    while(*str && digits--) {
+       d = *str >= 'A'? *str - 'A' + 10 : *str - '0';
+       v = v * 16 + d;
+       str++;
+    }
+    return v;
+}
+
+
+static proto_t *handle2ptr(str)
+char *str;
+{
+    int ofs, i;
+
+    if(strlen(str) != HANDLE_CHARS)
+       return NULL;
+
+    ofs = unhex(str, OFS_DIGITS);
+    str += OFS_DIGITS;
+    if(ofs < 0 || ofs >= proto_handles)
+       return NULL;
+
+    if(*str++ != '-')
+       return NULL;
+
+    for(i=0; i < PTR_CHARS; i++) {
+       hu.c[i] = unhex(str, CHAR_DIGITS);
+       str += CHAR_DIGITS;
+    }
+
+    if(proto_handle_table[ofs] != hu.p)
+       return NULL;
+
+    return hu.p;
+}
+
+
+static char *ptr2handle(p)
+proto_t *p;
+{
+    int i;
+    char *s;
+    static char hstr[HANDLE_CHARS+1];
+
+    assert(p->handleofs != -1 && proto_handle_table[p->handleofs] == p);
+
+    hu.p = p;
+
+    hex(hstr, OFS_DIGITS, p->handleofs);
+    s = &hstr[OFS_DIGITS];
+    *s++ = '-';
+
+    for(i=0;i<PTR_CHARS;i++) {
+       hex(s, CHAR_DIGITS, hu.c[i]);
+       s += CHAR_DIGITS;
+    }
+    *s = '\0';
+    return hstr;
+}
+
+/* -------- */
+
+jmp_buf parse_failed;
+char *parse_errmsg = NULL;
+
+static void eat_string(msg, str)
+dgram_t *msg;
+char *str;
+{
+    char *saved_str, *saved_msg;
+
+    /* eat leading whitespace */
+    while(isspace((int)(*msg->cur))) msg->cur++;
+
+    saved_msg = msg->cur;
+    saved_str = str;
+
+    /* eat any characters that match str */
+    while(*str && *msg->cur++ == *str++);
+
+    /* if we didn't eat all of str, we've failed */
+    if(*str) {
+       int len = strlen(saved_str);
+       char *tmp = NULL;
+       
+       tmp = alloc(len+1);
+       strncpy(tmp, saved_msg, len);
+       tmp[len] = '\0';
+       parse_errmsg = newvstralloc(parse_errmsg,
+                                   "expected \"", saved_str, "\",",
+                                   " got \"", tmp, "\"",
+                                   NULL);
+       amfree(tmp);
+       longjmp(parse_failed,1);
+    }
+}
+
+static int parse_integer(msg)
+dgram_t *msg;
+{
+    int i = 0;
+    int sign = 1;
+
+    /* eat leading whitespace */
+    while(isspace((int)(*msg->cur))) msg->cur++;
+
+    /* handle negative values */
+    if(*msg->cur == '-') {
+       sign = -1;
+       msg->cur++;
+    }
+
+    /* must have at least one digit */
+    if(*msg->cur < '0' || *msg->cur > '9') {
+       char non_digit[2];
+
+       non_digit[0] = *msg->cur;
+       non_digit[1] = '\0';
+       parse_errmsg = newvstralloc(parse_errmsg,
+                                   "expected digit, got \"", non_digit, "\"",
+                                   NULL);
+       longjmp(parse_failed,1);
+    }
+
+    while(*msg->cur >= '0' && *msg->cur <= '9') {
+       i = i * 10 + (*msg->cur - '0');
+       msg->cur++;
+    }
+    return sign * i;
+}
+
+static char *parse_string(msg)
+dgram_t *msg;
+{
+    char *str;
+
+    /* eat leading whitespace */
+    while(isspace((int)(*msg->cur))) msg->cur++;
+
+    /* mark start of string */
+    str = msg->cur;
+
+    /* stop at whitespace (including newlines) or end-of-packet */
+    while(*msg->cur && !isspace((int)(*msg->cur))) msg->cur++;
+
+    /* empty fields not allowed */
+    if(msg->cur == str) {
+       parse_errmsg = newstralloc(parse_errmsg,
+                                  "expected string, got empty field");
+       longjmp(parse_failed,1);
+    }
+
+    /* mark end of string in the packet, but don't fall off the end of it */
+    if(*msg->cur) *msg->cur++ = '\0';
+
+    return str;
+}
+
+static char *parse_line(msg)
+dgram_t *msg;
+{
+    char *str;
+
+    /* eat leading whitespace */
+    while(isspace((int)(*msg->cur))) msg->cur++;
+
+    /* mark start of string */
+    str = msg->cur;
+
+    /* stop at end of line or end-of-packet */
+    while(*msg->cur && *msg->cur != '\n') msg->cur++;
+
+    /* empty fields not allowed */
+    if(msg->cur == str) {
+       parse_errmsg = newstralloc(parse_errmsg,
+                                  "expected string, got empty field");
+       longjmp(parse_failed,1);
+    }
+
+    /* mark end of string in the packet, but don't fall off the end of it */
+    if(*msg->cur) *msg->cur++ = '\0';
+
+    return str;
+}
+
+void parse_pkt_header(pkt)
+pkt_t *pkt;
+{
+    dgram_t *msg;
+    char *typestr;
+
+    if(setjmp(parse_failed)) {
+/*     dbprintf(("%s: leftover:\n----\n%s----\n\n", errmsg, msg->cur)); */
+       pkt->type = P_BOGUS;
+       return;
+    }
+
+    msg = &pkt->dgram;
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: parsing packet:\n-------\n%s-------\n\n",
+             debug_prefix_time(": protocol"),
+             msg->cur));
+#endif
+
+    eat_string(msg, "Amanda");     pkt->version_major = parse_integer(msg);
+    eat_string(msg, ".");          pkt->version_minor = parse_integer(msg);
+    typestr = parse_string(msg);
+
+    if(strcmp(typestr, "REQ") == 0) pkt->type = P_REQ;
+    else if(strcmp(typestr, "REP") == 0) pkt->type = P_REP;
+    else if(strcmp(typestr, "ACK") == 0) pkt->type = P_ACK;
+    else if(strcmp(typestr, "NAK") == 0) pkt->type = P_NAK;
+    else pkt->type = P_BOGUS;
+
+    eat_string(msg, "HANDLE");     pkt->handle = parse_string(msg);
+    eat_string(msg, "SEQ");        pkt->sequence = parse_integer(msg);
+
+    eat_string(msg, "");
+#define sc "SECURITY "
+    if(strncmp(msg->cur, sc, sizeof(sc)-1) == 0) {
+       /* got security tag */
+       eat_string(msg, sc);
+#undef sc
+       pkt->security = parse_line(msg);
+    }
+    else pkt->security = NULL;
+
+    if(pkt->type == P_REQ) {
+
+#ifdef KRB4_SECURITY
+        eat_string(msg, "");
+        pkt->cksum = kerberos_cksum(msg->cur);
+#ifdef PROTO_DEBUG
+        dbprintf(("%s: parse_pkt/cksum %ld over \'%s\'\n\n",
+                 debug_prefix_time(": protocol"),
+                 pkt->cksum,
+                 msg->cur)); 
+#endif
+        fflush(stdout);
+#endif
+       eat_string(msg, "SERVICE");     pkt->service = parse_string(msg);
+    }
+
+    eat_string(msg, "");
+    pkt->body = msg->cur;
+}
+
+static void setup_dgram(p, msg, security, typestr)
+proto_t *p;
+dgram_t *msg;
+char *security, *typestr;
+{
+    char *linebuf = NULL;
+    char major_str[NUM_STR_SIZE];
+    char minor_str[NUM_STR_SIZE];
+    char seq_str[NUM_STR_SIZE];
+
+    ap_snprintf(major_str, sizeof(major_str), "%d", VERSION_MAJOR);
+    ap_snprintf(minor_str, sizeof(minor_str), "%d", VERSION_MINOR);
+    ap_snprintf(seq_str, sizeof(seq_str), "%d", p->curseq);
+
+    dgram_zero(msg);
+    dgram_socket(msg,proto_socket);
+    linebuf = vstralloc("Amanda ", major_str, ".", minor_str,
+                       " ", typestr,
+                       " HANDLE ", ptr2handle(p),
+                       " SEQ ", seq_str,
+                       "\n",
+                       security ? security : "",
+                       security ? "\n" : "",
+                       NULL);
+    dgram_cat(msg, linebuf);
+    amfree(linebuf);
+}
+
+static void send_req(p)
+proto_t *p;
+{
+    dgram_t outmsg;
+
+    setup_dgram(p, &outmsg, p->security, "REQ");
+    dgram_cat(&outmsg, p->req);
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: send_req: len %d: packet:\n----\n%s----\n\n", 
+             debug_prefix_time(": protocol"),
+             outmsg.len,
+             outmsg.data));
+#endif
+
+    if(dgram_send_addr(p->peer, &outmsg))
+       fprintf(stderr,"send req failed: %s\n", strerror(errno));
+}
+
+static void send_ack(p)
+proto_t *p;
+{
+    dgram_t outmsg;
+
+    setup_dgram(p, &outmsg, NULL, "ACK");
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: send_ack: len %d: packet:\n----\n%s----\n\n", 
+             debug_prefix_time(": protocol"),
+             outmsg.len,
+             outmsg.data));
+#endif
+
+    if(dgram_send_addr(p->peer, &outmsg))
+       error("send ack failed: %s", strerror(errno));
+}
+
+static void send_ack_repl(pkt)
+pkt_t *pkt;
+{
+    dgram_t outmsg;
+    char *linebuf = NULL;
+    char major_str[NUM_STR_SIZE];
+    char minor_str[NUM_STR_SIZE];
+    char seq_str[NUM_STR_SIZE];
+
+    ap_snprintf(major_str, sizeof(major_str), "%d", VERSION_MAJOR);
+    ap_snprintf(minor_str, sizeof(minor_str), "%d", VERSION_MINOR);
+    ap_snprintf(seq_str, sizeof(seq_str), "%d", pkt->sequence);
+
+    dgram_zero(&outmsg);
+    dgram_socket(&outmsg,proto_socket);
+
+    linebuf = vstralloc("Amanda ", major_str, ".", minor_str,
+                       " ACK HANDLE ", pkt->handle,
+                       " SEQ ", seq_str,
+                       "\n", NULL);
+
+    dgram_cat(&outmsg, linebuf);
+    amfree(linebuf);
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: send_ack_repl: len %d: packet:\n----\n%s----\n\n", 
+             debug_prefix_time(": protocol"),
+             outmsg.len,
+             outmsg.data));
+#endif
+
+    if(dgram_send_addr(pkt->peer, &outmsg))
+       error("send ack failed: %s", strerror(errno));
+}
+
+
+static void state_machine(p, action, pkt)
+proto_t *p;
+action_t action;
+pkt_t *pkt;
+{
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: state_machine: p %X state %s action %s%s%s\n",
+             debug_prefix_time(": protocol"),
+             (int)p,
+             prnpstate(p->state),
+             prnaction(action),
+             pkt == NULL? "" : " pktype ",
+             pkt == NULL? "" : prnpktype(pkt->type)));
+#endif
+
+    while(1) {
+       p->prevstate = p->state;
+       switch(p->state) {
+       case S_STARTUP: 
+           if(action != A_START) goto badaction;
+           p->origseq = p->curseq = proto_global_seq++;
+           p->reqtries = REQ_TRIES;
+           p->state = S_SENDREQ;
+           p->acktries = ACK_TRIES;
+           alloc_handle(p);
+           break;
+
+       case S_SENDREQ:
+           send_req(p);
+           p->curtime = CURTIME;
+           if(p->curseq == p->origseq) p->origtime = p->curtime;
+           p->timeout = time(0) + ACK_WAIT;
+           p->state = S_ACKWAIT;
+           pending_enqueue(p);
+           return;
+
+       case S_ACKWAIT:
+           if(action == A_TIMEOUT) {
+               if(--p->acktries == 0) {
+                   p->state = S_FAILED;
+                   free_handle(p);
+                   p->continuation(p, NULL);
+                   amfree(p->req);
+                   amfree(p->security);
+                   amfree(p);
+                   return;
+               }
+               else {
+                   p->state = S_SENDREQ;
+                   break;
+               }
+           }
+           else if(action != A_RCVDATA)
+               goto badaction;
+
+           /* got the packet with the right handle, now check it */
+
+#ifdef PROTO_DEBUG
+           dbprintf((
+         "%s: RESPTIME p %X pkt %s (t %d s %d) orig (t %d s %d) cur (t %d s %d)\n",
+                   debug_prefix_time(": protocol"),
+                   (int)p, prnpktype(pkt->type), 
+                   (int)CURTIME, relseq(pkt->sequence),
+                   (int)p->origtime, relseq(p->origseq), 
+                   (int)p->curtime, relseq(p->curseq)));
+#endif
+
+           if(pkt->type == P_ACK) {
+               if(pkt->sequence != p->origseq)
+                   p->reqtries--;
+               p->state = S_REPWAIT;
+               p->timeout = time(0) + p->repwait;
+               pending_enqueue(p);
+               return;
+           }
+           else if(pkt->type == P_NAK) {
+               p->state = S_FAILED;
+               free_handle(p);
+               p->continuation(p, pkt);
+               amfree(p->req);
+               amfree(p->security);
+               amfree(p);
+               return;
+           }
+           else if(pkt->type == P_REP) {
+               /* no ack, just rep */
+               p->state = S_REPWAIT;
+               break;
+           }
+           /* else unexpected packet, put back on queue */
+           pending_enqueue(p);
+           return;
+
+       case S_REPWAIT:
+           if(action == A_TIMEOUT) {
+               if(p->reqtries == 0 || 
+                  (CURTIME - p->origtime > DROP_DEAD_TIME)) {
+                   p->state = S_FAILED;
+                   free_handle(p);
+                   p->continuation(p, NULL);
+                   amfree(p->req);
+                   amfree(p->security);
+                   amfree(p);
+                   return;
+               }
+               else {
+                   p->reqtries--;
+                   p->state = S_SENDREQ;
+                   p->acktries = ACK_TRIES;
+                   break;
+               }
+           }
+           else if(action != A_RCVDATA)
+               goto badaction;
+           /* got the packet with the right handle, now check it */
+           if(pkt->type != P_REP) {
+               pending_enqueue(p);
+               return;
+           }
+           send_ack(p);
+           p->state = S_SUCCEEDED;
+           free_handle(p);
+           p->continuation(p, pkt);
+           amfree(p->req);
+           amfree(p->security);
+           amfree(p);
+           return;
+
+       default:
+       badaction:
+           error("protocol error: no handler for state %s action %s\n",
+                 prnpstate(p->state), prnaction(action));
+       }
+    }
+}
+
+static void add_bsd_security(p)
+proto_t *p;
+{
+    p->security = get_bsd_security();
+}
+
+int make_request(hostname, port, req, datap, repwait, continuation)
+char *hostname;
+int port;
+char *req;
+void *datap;
+time_t repwait;
+void (*continuation) P((proto_t *p, pkt_t *pkt));
+{
+    proto_t *p;
+    struct hostent *hp;
+
+
+    p = alloc(sizeof(proto_t));
+    p->state = S_STARTUP;
+    p->prevstate = S_STARTUP;
+    p->continuation = continuation;
+    p->req = req;
+    p->repwait = repwait;
+    p->datap = datap;
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: make_request: host %s -> p %X\n", 
+             debug_prefix_time(": protocol"),
+             hostname,
+             (int)p));
+#endif
+
+    if((hp = gethostbyname(hostname)) == 0) return -1;
+    memcpy(&p->peer.sin_addr, hp->h_addr, hp->h_length);
+    p->peer.sin_family = AF_INET;
+    p->peer.sin_port = htons(port);
+
+    add_bsd_security(p);
+
+    state_machine(p, A_START, NULL);
+    return 0;
+}
+
+#ifdef KRB4_SECURITY
+
+static int add_krb_security P((proto_t *p, char *host_inst, char *realm));
+
+static int add_krb_security(p, host_inst, realm)
+proto_t *p;
+char *host_inst, *realm;
+{
+    p->security = get_krb_security(p->req, host_inst, realm, &p->auth_cksum);
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: add_krb_security() cksum: %lu: \'%s\'\n",
+             debug_prefix_time(": protocol"),
+             p->auth_cksum,
+             p->req));
+#endif
+
+    return p->security == NULL;
+}
+
+int make_krb_request(hostname, port, req, datap, repwait, continuation)
+char *hostname;
+int port;
+char *req;
+void *datap;
+time_t repwait;
+void (*continuation) P((proto_t *p, pkt_t *pkt));
+{
+    proto_t *p;
+    struct hostent *hp;
+    char inst[256], realm[256];
+    int rc;
+
+    p = alloc(sizeof(proto_t));
+    p->state = S_STARTUP;
+    p->prevstate = S_STARTUP;
+    p->continuation = continuation;
+    p->req = req;
+    p->repwait = repwait;
+    p->datap = datap;
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: make_krb_request: host %s -> p %X\n", 
+             debug_prefix_time(": protocol"),
+             hostname,
+             req, (int)p));
+#endif
+
+    if((hp = host2krbname(hostname, inst, realm)) == 0)
+       return -1;
+    memcpy(&p->peer.sin_addr, hp->h_addr, hp->h_length);
+    p->peer.sin_family = AF_INET;
+    p->peer.sin_port = htons(port);
+
+    if((rc = add_krb_security(p, inst, realm)))
+       return rc;
+
+    state_machine(p, A_START, NULL);
+    return 0;
+}
+
+#endif
+
+static int select_til(waketime) 
+time_t waketime;
+{
+    fd_set ready;
+    struct timeval to;
+    time_t waittime;
+    int rc;
+
+    waittime = waketime - time(0);
+    if(waittime < 0) waittime = 0;     /* just poll */
+
+    FD_ZERO(&ready);
+    FD_SET(proto_socket, &ready);
+    to.tv_sec = waittime;
+    to.tv_usec = 0;
+
+    rc = select(proto_socket+1, (SELECT_ARG_TYPE *)&ready, NULL, NULL, &to);
+    if(rc == -1) {
+       error("protocol socket select: %s", strerror(errno));
+    }
+    return rc;
+}
+
+static int packet_arrived() 
+{
+    return select_til(0);
+}
+
+static void handle_incoming_packet() 
+{
+    pkt_t inpkt;
+    proto_t *p;
+
+    dgram_zero(&inpkt.dgram);
+    dgram_socket(&inpkt.dgram, proto_socket);
+    if(dgram_recv(&inpkt.dgram, 0, &inpkt.peer) == -1) {
+#ifdef ECONNREFUSED
+       if(errno == ECONNREFUSED)
+           return;
+#endif
+#ifdef EAGAIN
+       if(errno == EAGAIN)
+           return;
+#endif
+
+       fprintf(stderr,"protocol packet receive: %s\n", strerror(errno));
+    }
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: got packet:\n----\n%s----\n\n",
+             debug_prefix_time(": protocol"),
+             inpkt.dgram.data));
+#endif
+
+    parse_pkt_header(&inpkt);
+    if(inpkt.type == P_BOGUS)
+       return;
+    if((p = handle2ptr(inpkt.handle)) == NULL) {
+       /* ack succeeded reps */
+       if(inpkt.type == P_REP)
+           send_ack_repl(&inpkt);
+       return;
+    }
+
+#ifdef PROTO_DEBUG
+    dbprintf(("%s: handle %s p %X got packet type %s\n",
+             debug_prefix_time(": protocol"),
+             inpkt.handle,
+             (int)p,
+             prnpktype(inpkt.type)));
+#endif
+
+    pending_remove(p);
+    state_machine(p, A_RCVDATA, &inpkt);
+}
+
+
+
+void check_protocol()
+{
+    time_t curtime;
+    proto_t *p;
+
+    while(packet_arrived())
+       handle_incoming_packet();
+
+    curtime = time(0);
+    while(pending_head && curtime >= pending_head->timeout) {
+       p = pending_dequeue();
+       state_machine(p, A_TIMEOUT, NULL);
+    }
+}
+
+
+void run_protocol()
+{
+    time_t wakeup_time;
+    proto_t *p;
+
+    while(pending_head) {
+       wakeup_time = pending_head->timeout;
+
+#ifdef PROTO_DEBUG
+       dbprintf(("%s: run_protocol: waiting %d secs for %d pending reqs\n",
+                 debug_prefix_time(": protocol"),
+                 (int)(wakeup_time - time(0)),
+                 pending_qlength));
+#endif
+
+       if(select_til(wakeup_time))
+           handle_incoming_packet();
+       else {
+           p = pending_dequeue();
+           state_machine(p, A_TIMEOUT, NULL);
+       }
+    }
+}
diff --git a/common-src/protocol.h b/common-src/protocol.h
new file mode 100644 (file)
index 0000000..2900ec4
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * 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: protocol.h,v 1.8.10.3 2004/04/29 20:47:40 martinea Exp $
+ *
+ * interfaces for amanda protocol
+ */
+#ifndef PROTOCOL_H
+#define PROTOCOL_H
+
+#include "amanda.h"
+#include "dgram.h"
+
+typedef enum {
+    S_BOGUS,
+    S_STARTUP, S_SENDREQ, S_ACKWAIT, S_REPWAIT, S_SUCCEEDED, S_FAILED
+} pstate_t;
+
+typedef enum { A_BOGUS, A_START, A_TIMEOUT, A_RCVDATA } action_t;
+
+typedef enum { P_BOGUS, P_REQ, P_REP, P_ACK, P_NAK } pktype_t;
+
+typedef struct {                       /* a predigested datagram */
+    pktype_t type;
+    struct sockaddr_in peer;
+    uint32_t cksum;
+    int version_major, version_minor;
+    int sequence;
+    char *handle;
+    char *service;
+    char *security;
+    char *body;
+    dgram_t dgram;
+} pkt_t;
+
+typedef struct proto_s {
+    pstate_t state;
+    pstate_t prevstate;
+    struct sockaddr_in peer;
+    time_t timeout;
+    time_t repwait;
+    time_t origtime, curtime;
+    int reqtries, acktries;
+    int origseq, curseq;
+    int handleofs;
+    char *security;
+    uint32_t auth_cksum;
+    char *req;                                 /* body of request msg */
+    void (*continuation) P((struct proto_s *, pkt_t *));
+    void *datap;
+    struct proto_s *prev,*next;
+} proto_t;
+
+void proto_init P((int sock, int startseq, int handles));
+int make_request P((char *hostname, int port, char *req, void *datap,
+                   time_t repwait, 
+                   void (*continuation) P((proto_t *p, pkt_t *pkt))
+                   ));
+
+void check_protocol P((void));
+void run_protocol P((void));
+
+void parse_pkt_header P((pkt_t *pkt));
+
+#ifdef KRB4_SECURITY
+int make_krb_request P((char *hostname, int port, char *req,
+                       void *datap, time_t repwait,
+                       void (*continuation) P((proto_t *p, pkt_t *pkt))
+                       ));
+#endif
+
+extern char *parse_errmsg;
+
+#endif /* PROTOCOL_H */
diff --git a/common-src/regcomp.c b/common-src/regcomp.c
new file mode 100644 (file)
index 0000000..fbdc7b1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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: regcomp.c,v 1.3 1998/07/04 00:18:51 oliva Exp $
+ *
+ * wrapper file for Henry Spencer's regcomp.c
+ */
+
+#include "amregex.h"
+#include "../regex-src/regcomp.c"
diff --git a/common-src/regerror.c b/common-src/regerror.c
new file mode 100644 (file)
index 0000000..04cd760
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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: regerror.c,v 1.3 1998/07/04 00:18:52 oliva Exp $
+ *
+ * wrapper file for Henry Spencer's regerror.c
+ */
+
+#include "amregex.h"
+#include "../regex-src/regerror.c"
diff --git a/common-src/regexec.c b/common-src/regexec.c
new file mode 100644 (file)
index 0000000..27f0dd5
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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: regexec.c,v 1.3 1998/07/04 00:18:53 oliva Exp $
+ *
+ * wrapper file for Henry Spencer's regexec.c
+ */
+
+#include "amregex.h"
+#include "../regex-src/regexec.c"
diff --git a/common-src/regfree.c b/common-src/regfree.c
new file mode 100644 (file)
index 0000000..06ace3b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * 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: regfree.c,v 1.3 1998/07/04 00:18:54 oliva Exp $
+ *
+ * wrapper file for Henry Spencer's regfree.c
+ */
+
+#include "amregex.h"
+#include "../regex-src/regfree.c"
diff --git a/common-src/security.c b/common-src/security.c
new file mode 100644 (file)
index 0000000..018e7a2
--- /dev/null
@@ -0,0 +1,613 @@
+/*
+ * 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: security.c,v 1.17.2.6.4.1.2.6 2004/04/29 20:47:40 martinea Exp $
+ *
+ * wrapper file for kerberos security
+ */
+
+#include "amanda.h"
+#include "clock.h"
+
+/*
+ * 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 we don't have the new-style wait access functions, use our own,
+ * compatible with old-style BSD systems at least.  Note that we don't
+ * care about the case w_stopval == WSTOPPED since we don't ask to see
+ * stopped processes, so should never get them from wait.
+ */
+#ifndef WEXITSTATUS
+#   define WEXITSTATUS(r)       (((union wait *) &(r))->w_retcode)
+#   define WTERMSIG(r)          (((union wait *) &(r))->w_termsig)
+
+#   undef  WIFSIGNALED
+#   define WIFSIGNALED(r)       (((union wait *) &(r))->w_termsig != 0)
+#endif
+
+#if defined(TEST)                                              /* { */
+#define SHOW_SECURITY_DETAIL
+#undef dbprintf
+#define dbprintf(p)    printf p
+#endif                                                         /* } */
+
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+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) {
+       dbprintf(("%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);
+       ap_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);
+       ap_snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid);
+    } else {
+       group = stralloc(grptr->gr_name);
+    }
+    dbprintf(("%s: processing file: %s\n", debug_prefix_time(NULL), name));
+    dbprintf(("%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                                                         /* } */
+
+#ifdef KRB4_SECURITY                                           /* { */
+#include "krb4-security.c"
+#endif                                                         /* } */
+
+int bsd_security_ok P((struct sockaddr_in *addr,
+                      char *str, uint32_t cksum, char **errstr));
+
+char *get_bsd_security()
+{
+    struct passwd *pwptr;
+
+    if((pwptr = getpwuid(getuid())) == NULL)
+       error("can't get login name for my uid %ld", (long)getuid());
+    return stralloc2("SECURITY USER ", pwptr->pw_name);
+}
+
+int security_ok(addr, str, cksum, errstr)
+struct sockaddr_in *addr;
+char *str;
+uint32_t cksum;
+char **errstr;
+{
+#ifdef KRB4_SECURITY                                           /* { */
+    if(krb4_auth)
+       return krb4_security_ok(addr, str, cksum, errstr);
+    else
+#endif                                                         /* } */
+       return bsd_security_ok(addr, str, cksum, errstr);
+}
+
+#ifdef BSD_SECURITY                                            /* { */
+
+int bsd_security_ok(addr, str, cksum, errstr)
+     struct sockaddr_in *addr;
+     char *str;
+     uint32_t cksum;
+     char **errstr;
+{
+    char *remotehost = NULL, *remoteuser = NULL, *localuser = NULL;
+    char *bad_bsd = NULL;
+    struct hostent *hp;
+    struct passwd *pwptr;
+    int myuid, i, j;
+    char *s, *fp;
+    int ch;
+    char number[NUM_STR_SIZE];
+#ifdef USE_AMANDAHOSTS                                         /* { */
+    FILE *fPerm;
+    char *pbuf = NULL;
+    char *ptmp;
+    int pbuf_len;
+    int amandahostsauth = 0;
+#else                                                          /* } { */
+    FILE *fError;
+    int saved_stderr;
+    int fd[2];
+    amwait_t wait_exitcode;
+    int exitcode;
+    pid_t pid, ruserok_pid;
+#endif                                                         /* } */
+
+    *errstr = NULL;
+
+    /* what host is making the request? */
+
+    hp = gethostbyaddr((char *)&addr->sin_addr, (int)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) {
+       ap_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);
+    }
+
+    localuser = stralloc(pwptr->pw_name);
+
+    dbprintf(("%s: bsd security: remote host %s user %s local user %s\n",
+             debug_prefix_time(NULL), remotehost, remoteuser, localuser));
+
+#ifndef USE_AMANDAHOSTS                                                /* { */
+    /*
+     * Note that some versions of ruserok (eg SunOS 3.2) look in
+     * "./.rhosts" rather than "~localuser/.rhosts", so we have to
+     * change directories 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) {
+       error("error [pipe() fails]");
+    }
+    if ((ruserok_pid = fork ()) < 0) {
+       error("error [fork() fails]");
+    } else if (ruserok_pid == 0) {
+       close(fd[0]);
+       fError = fdopen(fd[1], "w");
+       /* pamper braindead ruserok's */
+       if(chdir(pwptr->pw_dir) != 0) {
+           fprintf(fError, "[chdir(%s) failed: %s]",
+                   pwptr->pw_dir, strerror(errno));
+           fclose(fError);
+           exit(1);
+       }
+
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+       {
+       char *dir = stralloc(pwptr->pw_dir);
+
+       dbprintf(("%s: calling ruserok(%s, %d, %s, %s)\n",
+                 debug_prefix_time(NULL),
+                 remotehost, myuid == 0, remoteuser, localuser));
+       if (myuid == 0) {
+           dbprintf(("%s: because you are running as root, ",
+                     debug_prefix(NULL)));
+           dbprintf(("/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);
+       (void)open("/dev/null", 2);
+
+       if(ruserok(remotehost, myuid == 0, remoteuser, localuser) == -1) {
+           dup2(saved_stderr,2);
+           close(saved_stderr);
+           *errstr = vstralloc("[",
+                               "access as ", localuser, " not allowed",
+                               " from ", remoteuser, "@", remotehost,
+                               "] ruserok failed",
+                               NULL);
+           fputs(*errstr, fError);
+           fputc('\n', fError);
+           fclose(fError);
+           dbprintf(("%s: check failed: %s\n",
+                     debug_prefix_time(NULL), *errstr));
+           amfree(*errstr);
+           exit(1);
+       }
+
+       dup2(saved_stderr,2);
+       close(saved_stderr);
+       dbprintf(("%s: bsd security check to %s from %s@%s passed\n",
+                 debug_prefix_time(NULL),
+                 localuser, remoteuser, remotehost));
+       amfree(remotehost);
+       amfree(remoteuser);
+       amfree(remoteuser);
+       exit(0);
+    }
+    close(fd[1]);
+    fError = fdopen(fd[0], "r");
+
+    while((pid = wait(&wait_exitcode)) == (pid_t)-1 && errno == EINTR) {}
+    if (pid == (pid_t)-1) {
+       *errstr = vstralloc("[",
+                           "access as ", localuser, " not allowed",
+                           " from ", remoteuser, "@", remotehost,
+                           "] wait failed: ",
+                           strerror(errno),
+                           NULL);
+       exitcode = 0;
+    } else if (pid != ruserok_pid) {
+       ap_snprintf(number, sizeof(number), "%ld", (long)pid);
+       *errstr = vstralloc("[",
+                           "access as ", localuser, " not allowed",
+                           " from ", remoteuser, "@", remotehost,
+                           "] wait got pid ",
+                           number,
+                           NULL);
+       exitcode = 0;
+    } else if (WIFSIGNALED(wait_exitcode)) {
+       ap_snprintf(number, sizeof(number), "%d", WTERMSIG(wait_exitcode));
+       *errstr = vstralloc("[",
+                           "access as ", localuser, " not allowed",
+                           " from ", remoteuser, "@", remotehost,
+                           "] got signal ", number,
+                           NULL);
+       exitcode = 0;
+    } else {
+       exitcode = WEXITSTATUS(wait_exitcode);
+    }
+    if(exitcode) {
+       if((*errstr = agets(fError)) == NULL) {
+           *errstr = vstralloc("[",
+                               "access as ", localuser, " not allowed",
+                               " from ", remoteuser, "@", remotehost,
+                               "] could not get result",
+                               NULL);
+       }
+    }
+    fclose(fError);
+    amfree(remotehost);
+    amfree(localuser);
+    amfree(remoteuser);
+    return *errstr == NULL;
+#else                                                          /* } { */
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+    show_stat_info(pwptr->pw_dir, "/.amandahosts");
+#endif                                                         /* } */
+
+    ptmp = stralloc2(pwptr->pw_dir, "/.amandahosts");
+    if((fPerm = fopen(ptmp, "r")) == NULL) {
+       /*
+        * Put an explanation in the amandad.debug log that will help a
+        * system administrator fix the problem, but don't send a clue
+        * back to the other end to tell them what to fix in order to
+        * be able to hack our system.
+         */
+       dbprintf(("%s: fopen of %s failed: %s\n",
+                 debug_prefix_time(NULL), ptmp, strerror(errno)));
+       *errstr = vstralloc("[",
+                           "access as ", localuser, " not allowed",
+                           " from ", remoteuser, "@", remotehost,
+                           "] open of ",
+                           ptmp,
+                           " failed", NULL);
+       amfree(ptmp);
+       amfree(remotehost);
+       amfree(localuser);
+       amfree(remoteuser);
+       return 0;
+    }
+    amfree(ptmp);
+
+    for(; (pbuf = agets(fPerm)) != NULL; free(pbuf)) {
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+       dbprintf(("%s: processing line: <%s>\n", debug_prefix(NULL), pbuf));
+#endif                                                         /* } */
+       pbuf_len = strlen(pbuf);
+       s = pbuf;
+       ch = *s++;
+
+       /* Find end of remote host */
+       skip_non_whitespace(s, ch);
+       if(s - 1 == pbuf) {
+           memset(pbuf, '\0', pbuf_len);       /* leave no trace */
+           continue;                           /* no remotehost field */
+       }
+       s[-1] = '\0';                           /* terminate remotehost field */
+
+       /* Find start of remote user */
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           ptmp = localuser;                   /* no remoteuser field */
+       } else {
+           ptmp = s-1;                         /* start of remoteuser field */
+
+           /* Find end of remote user */
+           skip_non_whitespace(s, ch);
+           s[-1] = '\0';                       /* terminate remoteuser field */
+       }
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+       dbprintf(("%s: comparing %s with\n", debug_prefix(NULL), pbuf));
+       dbprintf(("%s:           %s (%s)\n",
+                 debug_prefix(NULL), remotehost,
+                 (strcasecmp(pbuf, remotehost) == 0) ? "match" : "no match"));
+       dbprintf(("%s:       and %s with\n", debug_prefix(NULL), ptmp));
+       dbprintf(("%s:           %s (%s)\n",
+                 debug_prefix(NULL), remoteuser,
+                 (strcasecmp(ptmp, remoteuser) == 0) ? "match" : "no match"));
+#endif                                                         /* } */
+       if(strcasecmp(pbuf, remotehost) == 0
+          && strcasecmp(ptmp, remoteuser) == 0) {
+           amandahostsauth = 1;
+           break;
+       }
+       memset(pbuf, '\0', pbuf_len);           /* leave no trace */
+    }
+    afclose(fPerm);
+    amfree(pbuf);
+
+    if(amandahostsauth) {
+       dbprintf(("%s: amandahosts security check passed\n",
+                 debug_prefix_time(NULL)));
+       amfree(remotehost);
+       amfree(localuser);
+       amfree(remoteuser);
+       return 1;
+    }
+
+    *errstr = vstralloc("[",
+                       "access as ", localuser, " not allowed",
+                       " from ", remoteuser, "@", remotehost,
+                       "] amandahostsauth failed", NULL);
+    dbprintf(("%s: check failed: %s\n", debug_prefix_time(NULL), *errstr));
+
+    amfree(remotehost);
+    amfree(localuser);
+    amfree(remoteuser);
+    return 0;
+
+#endif                                                         /* } */
+}
+
+#else  /* ! BSD_SECURITY */                                    /* } { */
+
+int bsd_security_ok(addr, str, cksum, errstr)
+struct sockaddr_in *addr;
+char *str;
+uint32_t cksum;
+char **errstr;
+{
+#if defined(SHOW_SECURITY_DETAIL)                              /* { */
+    dbprintf(("You configured Amanda using --without-bsd-security, so it\n"));
+    dbprintf(("will let anyone on the Internet connect and do dumps of\n"));
+    dbprintf(("your system unless you have some other kind of protection,\n"));
+    dbprintf(("such as a firewall or TCP wrappers.\n"));
+#endif                                                         /* } */
+    return 1;
+}
+
+#endif /* ! BSD_SECURITY */                                    /* } */
+
+#if defined(TEST)                                              /* { */
+
+int
+main (argc, argv)
+{
+    char *remoteuser;
+    char *remotehost;
+    struct hostent *hp;
+    struct sockaddr_in fake;
+    char *str;
+    char *errstr;
+    int r;
+    struct passwd      *pwent;
+
+    /*
+     * The following is stolen from amandad to emulate what it would
+     * do on startup.
+     */
+    if(client_uid == (uid_t) -1 && (pwent = getpwnam(CLIENT_LOGIN)) != NULL) {
+       client_uid = pwent->pw_uid;
+       client_gid = pwent->pw_gid;
+       endpwent();
+    }
+#ifdef FORCE_USERID
+
+    /* we'd rather not run as root */
+    if(geteuid() == 0) {
+#ifdef KRB4_SECURITY
+        if(client_uid == (uid_t) -1) {
+           error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
+       }
+
+        /*
+        * if we're using kerberos security, we'll need to be root in
+        * order to get at the machine's srvtab entry, so we hang on to
+        * some root privledges for now.  We give them up entirely later.
+        */
+       setegid(client_gid);
+       seteuid(client_uid);
+#else
+       initgroups(CLIENT_LOGIN, client_gid);
+       setgid(client_gid);
+       setuid(client_uid);
+#endif  /* KRB4_SECURITY */
+    }
+#endif /* FORCE_USERID */
+
+    fputs("Remote user: ", stdout);
+    fflush(stdout);
+    if ((remoteuser = agets(stdin)) == NULL) {
+       return 0;
+    }
+    str = stralloc2("USER ", remoteuser);
+
+    fputs("Remote host: ", stdout);
+    fflush(stdout);
+    if ((remotehost = agets(stdin)) == NULL) {
+       return 0;
+    }
+
+    set_pname("security");
+    startclock();
+
+    if ((hp = gethostbyname(remotehost)) == NULL) {
+       dbprintf(("%s: cannot look up remote host %s\n",
+                 debug_prefix_time(NULL), remotehost));
+       return 1;
+    }
+    memcpy((char *)&fake.sin_addr, (char *)hp->h_addr, sizeof(hp->h_addr));
+    fake.sin_port = htons(IPPORT_RESERVED - 1);
+
+    if ((r = bsd_security_ok(&fake, str, 0, &errstr)) == 0) {
+       dbprintf(("%s: security check of %s@%s failed\n",
+                 debug_prefix_time(NULL), remoteuser, remotehost));
+       dbprintf(("%s: %s\n", debug_prefix(NULL), errstr));
+    } else {
+       dbprintf(("%s: security check of %s@%s passed\n",
+                 debug_prefix_time(NULL), remoteuser, remotehost));
+    }
+    return r;
+}
+
+#endif                                                         /* } */
diff --git a/common-src/sl.c b/common-src/sl.c
new file mode 100644 (file)
index 0000000..a9f37ad
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                         Computer Science Department
+ *                         University of Maryland at College Park
+ */
+/*
+ * $Id: sl.c,v 1.1.2.3 2004/04/23 11:44:57 martinea Exp $
+ *
+ * A doubly linked list of string (char *)
+ */
+
+#include "amanda.h"
+#include "sl.h"
+
+
+void init_sl(sl)
+sl_t *sl;
+{
+    sl->first = NULL;
+    sl->last  = NULL;
+    sl->nb_element = 0;
+}
+
+
+sl_t *new_sl() {
+    sl_t *sl;
+    sl = alloc(sizeof(sl_t));
+    init_sl(sl);
+    return(sl);
+}
+
+
+sl_t *insert_sl(sl, name)
+sl_t *sl;
+char *name;
+{
+    sle_t *a;
+
+    if(!sl) {
+       sl = new_sl();
+    }
+    a = alloc(sizeof(sle_t));
+    a->name = stralloc(name);
+    a->next = sl->first;
+    a->prev = NULL;
+    if(a->next)
+       a->next->prev = a;
+    else
+       sl->last = a;
+    sl->first = a;
+    sl->nb_element++;
+    return(sl);
+}
+
+
+sl_t *append_sl(sl, name)
+sl_t *sl;
+char *name;
+{
+    sle_t *a;
+
+    if(!sl) {
+       sl = new_sl();
+    }
+    a = alloc(sizeof(sle_t));
+    a->name = stralloc(name);
+    a->prev = sl->last;
+    a->next = NULL;
+    if(a->prev)
+       a->prev->next = a;
+    else
+       sl->first = a;
+    sl->last = a;
+    sl->nb_element++;
+    return(sl);
+}
+
+
+sl_t *insert_sort_sl(sl, name)
+sl_t *sl;
+char *name;
+{
+    sle_t *a, *b;
+
+    if(!sl) {
+       sl = new_sl();
+    }
+
+    for(b=sl->first; b != NULL < 0; b=b->next) {
+       int i = strcmp(b->name, name);
+       if(i==0) return(sl); /* already there, no need to insert */
+       if(i>0) break;
+    }
+
+    if(b == sl->first) return insert_sl(sl, name);
+    if(b == NULL)      return append_sl(sl, name);
+
+    a = alloc(sizeof(sle_t));
+    a->name = stralloc(name);
+
+    /* insert before b */
+    a->next = b;
+    a->prev = b->prev;
+    b->prev->next = a;
+    b->prev = a;
+    sl->nb_element++;
+    return(sl);
+}
+
+
+void free_sl(sl)
+sl_t *sl;
+{
+    sle_t *a, *b;
+
+    if(!sl) return;
+
+    a = sl->first;
+    while(a != NULL) {
+       b = a;
+       a = a->next;
+       amfree(b->name);
+       amfree(b);
+    }
+    amfree(sl);
+}
+
+
+void remove_sl(sl, elem)
+sl_t *sl;
+sle_t *elem;
+{
+    if(elem->prev)
+       elem->prev->next = elem->next;
+    else
+       sl->first = elem->next;
+
+    if(elem->next)
+       elem->next->prev = elem->prev;
+    else
+       sl->last = elem->prev;
+
+    sl->nb_element--;
+
+    amfree(elem->name);
+    amfree(elem);
+}
+
+
+sl_t *duplicate_sl(sl)
+sl_t *sl;
+{
+    sl_t *new_sl = NULL;
+    sle_t *a;
+
+    if(!sl) return new_sl;
+
+    for(a = sl->first; a != NULL; a = a->next) {
+       new_sl = append_sl(new_sl, a->name);
+    }
+
+    return new_sl;
+}
+
+/*
+ * Return "true" iff sl is empty (i.e. contains no elements).
+ */
+int is_empty_sl(sl)
+sl_t *sl;
+{
+    if (sl == NULL)
+       return 1;
+
+    return (sl->nb_element == 0);
+}
diff --git a/common-src/sl.h b/common-src/sl.h
new file mode 100644 (file)
index 0000000..f5e75fb
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                         Computer Science Department
+ *                         University of Maryland at College Park
+ */
+/*
+ * $Id: sl.h,v 1.1.2.2 2004/04/23 11:44:57 martinea Exp $
+ *
+ * A doubly linked list of string (char *)
+ */
+
+/*
+ * To scan over all element of the list
+ *
+ *    for(sle=sl->first; sle != NULL; sle = sle->next) {
+ *    }
+ */
+#ifndef STRINGLIST_H
+#define STRINGLIST_H
+
+#include "amanda.h"
+
+typedef struct sle_s {
+    struct sle_s *next, *prev;
+    char *name;
+} sle_t;
+
+typedef struct sl_s {
+    struct sle_s *first, *last;
+    int nb_element;
+} sl_t;
+
+void init_sl 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));
+
+#endif
diff --git a/common-src/snprintf.c b/common-src/snprintf.c
new file mode 100644 (file)
index 0000000..10ec588
--- /dev/null
@@ -0,0 +1,1037 @@
+/* ====================================================================
+ * Copyright (c) 1995-1997 The Apache Group.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * 4. The names "Apache Server" and "Apache Group" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission.
+ *
+ * 5. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the Apache Group
+ *    for use in the Apache HTTP server project (http://www.apache.org/)."
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Group and was originally based
+ * on public domain software written at the National Center for
+ * Supercomputing Applications, University of Illinois, Urbana-Champaign.
+ * For more information on the Apache Group and the Apache HTTP server
+ * project, please see <http://www.apache.org/>.
+ *
+ * This code is based on, and used with the permission of, the
+ * SIO stdio-replacement strx_* functions by Panos Tsirigotis
+ * <panos@alumni.cs.colorado.edu> for xinetd.
+ */
+
+/* #include "conf.h"   -- original line from the Apache distribution */
+/*
+ * These are what we need in Amanda.
+ */
+#include "amanda.h"
+#include "arglist.h"
+#include <math.h>
+
+#if !(defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF))
+
+/*
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+*/
+
+#ifdef HAVE_CVT
+
+# define ap_ecvt ecvt
+# define ap_fcvt fcvt
+# define ap_gcvt gcvt
+
+#else
+
+/*
+ * cvt.c - IEEE floating point formatting routines for FreeBSD
+ * from GNU libc-4.6.27
+ */
+
+/*
+ *    ap_ecvt converts to decimal
+ *      the number of digits is specified by ndigit
+ *      decpt is set to the position of the decimal point
+ *      sign is set to 0 for positive, 1 for negative
+ */
+
+#define        NDIG    80
+
+/*
+static char *
+     ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag)
+*/
+static char *ap_cvt(arg, ndigits, decpt, sign, eflag)
+double arg;
+int ndigits;
+int *decpt;
+int *sign;
+int eflag;
+{
+    register int r2;
+    double fi, fj;
+    register char *p, *p1;
+    static char buf[NDIG];
+
+    if (ndigits >= NDIG - 1)
+       ndigits = NDIG - 2;
+    r2 = 0;
+    *sign = 0;
+    p = &buf[0];
+    if (arg < 0) {
+       *sign = 1;
+       arg = -arg;
+    }
+    arg = modf(arg, &fi);
+    p1 = &buf[NDIG];
+    /*
+     * Do integer part
+     */
+    if (fi != 0) {
+       p1 = &buf[NDIG];
+       while (fi != 0) {
+           fj = modf(fi / 10, &fi);
+           *--p1 = (int) ((fj + .03) * 10) + '0';
+           r2++;
+       }
+       while (p1 < &buf[NDIG])
+           *p++ = *p1++;
+    }
+    else if (arg > 0) {
+       while ((fj = arg * 10) < 1) {
+           arg = fj;
+           r2--;
+       }
+    }
+    p1 = &buf[ndigits];
+    if (eflag == 0)
+       p1 += r2;
+    *decpt = r2;
+    if (p1 < &buf[0]) {
+       buf[0] = '\0';
+       return (buf);
+    }
+    while (p <= p1 && p < &buf[NDIG]) {
+       arg *= 10;
+       arg = modf(arg, &fj);
+       *p++ = (int) fj + '0';
+    }
+    if (p1 >= &buf[NDIG]) {
+       buf[NDIG - 1] = '\0';
+       return (buf);
+    }
+    p = p1;
+    *p1 += 5;
+    while (*p1 > '9') {
+       *p1 = '0';
+       if (p1 > buf)
+           ++ * --p1;
+       else {
+           *p1 = '1';
+           (*decpt)++;
+           if (eflag == 0) {
+               if (p > buf)
+                   *p = '0';
+               p++;
+           }
+       }
+    }
+    *p = '\0';
+    return (buf);
+}
+
+/*
+static char *
+     ap_ecvt(double arg, int ndigits, int *decpt, int *sign)
+*/
+static char *ap_ecvt(arg, ndigits, decpt, sign)
+double arg;
+int ndigits;
+int *decpt;
+int *sign;
+{
+    return (ap_cvt(arg, ndigits, decpt, sign, 1));
+}
+
+/*
+static char *
+     ap_fcvt(double arg, int ndigits, int *decpt, int *sign)
+*/
+static char *ap_fcvt(arg, ndigits, decpt, sign)
+double arg;
+int ndigits;
+int *decpt;
+int *sign;
+{
+    return (ap_cvt(arg, ndigits, decpt, sign, 0));
+}
+
+/*
+ * ap_gcvt  - Floating output conversion to
+ * minimal length string
+ */
+/*
+static char *
+     ap_gcvt(double number, int ndigit, char *buf)
+*/
+static char *ap_gcvt(number, ndigit, buf)
+double number;
+int ndigit;
+char *buf;
+{
+    int sign, decpt;
+    register char *p1, *p2;
+    register i;
+
+    p1 = ap_ecvt(number, ndigit, &decpt, &sign);
+    p2 = buf;
+    if (sign)
+       *p2++ = '-';
+    for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
+       ndigit--;
+    if ((decpt >= 0 && decpt - ndigit > 4)
+       || (decpt < 0 && decpt < -3)) {         /* use E-style */
+       decpt--;
+       *p2++ = *p1++;
+       *p2++ = '.';
+       for (i = 1; i < ndigit; i++)
+           *p2++ = *p1++;
+       *p2++ = 'e';
+       if (decpt < 0) {
+           decpt = -decpt;
+           *p2++ = '-';
+       }
+       else
+           *p2++ = '+';
+       if (decpt / 100 > 0)
+           *p2++ = decpt / 100 + '0';
+       if (decpt / 10 > 0)
+           *p2++ = (decpt % 100) / 10 + '0';
+       *p2++ = decpt % 10 + '0';
+    }
+    else {
+       if (decpt <= 0) {
+           if (*p1 != '0')
+               *p2++ = '.';
+           while (decpt < 0) {
+               decpt++;
+               *p2++ = '0';
+           }
+       }
+       for (i = 1; i <= ndigit; i++) {
+           *p2++ = *p1++;
+           if (i == decpt)
+               *p2++ = '.';
+       }
+       if (ndigit < decpt) {
+           while (ndigit++ < decpt)
+               *p2++ = '0';
+           *p2++ = '.';
+       }
+    }
+    if (p2[-1] == '.')
+       p2--;
+    *p2 = '\0';
+    return (buf);
+}
+
+#endif /* HAVE_CVT */
+
+typedef enum {
+    NO = 0, YES = 1
+} boolean_e;
+
+#define FALSE                  0
+#define TRUE                   1
+#define NUL                    '\0'
+#define INT_NULL               ((int *)0)
+#define WIDE_INT               long
+
+typedef WIDE_INT               wide_int;
+typedef unsigned WIDE_INT      u_wide_int;
+typedef int                    bool_int;
+
+#define S_NULL                 "(null)"
+#define S_NULL_LEN             6
+
+#define FLOAT_DIGITS           6
+#define EXPONENT_LENGTH                10
+
+/*
+ * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
+ *
+ * XXX: this is a magic number; do not decrease it
+ */
+#define NUM_BUF_SIZE           512
+
+
+/*
+ * Descriptor for buffer area
+ */
+struct buf_area {
+    char *buf_end;
+    char *nextb;               /* pointer to next byte to read/write   */
+};
+
+typedef struct buf_area buffy;
+
+/*
+ * The INS_CHAR macro inserts a character in the buffer and writes
+ * the buffer back to disk if necessary
+ * It uses the char pointers sp and bep:
+ *      sp points to the next available character in the buffer
+ *      bep points to the end-of-buffer+1
+ * While using this macro, note that the nextb pointer is NOT updated.
+ *
+ * NOTE: Evaluation of the c argument should not have any side-effects
+ */
+#define INS_CHAR( c, sp, bep, cc )     \
+           {                           \
+               if ( sp < bep )         \
+               {                       \
+                   *sp++ = c ;         \
+                   cc++ ;              \
+               }                       \
+           }
+
+#define NUM( c )                       ( c - '0' )
+
+#define STR_TO_DEC( str, num )         \
+    num = NUM( *str++ ) ;              \
+    while ( isdigit( *str ) )          \
+    {                                  \
+       num *= 10 ;                     \
+       num += NUM( *str++ ) ;          \
+    }
+
+/*
+ * This macro does zero padding so that the precision
+ * requirement is satisfied. The padding is done by
+ * adding '0's to the left of the string that is going
+ * to be printed.
+ */
+#define FIX_PRECISION( adjust, precision, s, s_len )   \
+    if ( adjust )                                      \
+       while ( s_len < precision )                     \
+       {                                               \
+           *--s = '0' ;                                \
+           s_len++ ;                                   \
+       }
+
+/*
+ * Macro that does padding. The padding is done by printing
+ * the character ch.
+ */
+#define PAD( width, len, ch )  do              \
+       {                                       \
+           INS_CHAR( ch, sp, bep, cc ) ;       \
+           width-- ;                           \
+       }                                       \
+       while ( width > len )
+
+/*
+ * Prefix the character ch to the string str
+ * Increase length
+ * Set the has_prefix flag
+ */
+#define PREFIX( str, length, ch )       *--str = ch ; length++ ; has_prefix = YES
+
+
+/*
+ * Convert num to its decimal format.
+ * Return value:
+ *   - a pointer to a string containing the number (no sign)
+ *   - len contains the length of the string
+ *   - is_negative is set to TRUE or FALSE depending on the sign
+ *     of the number (always set to FALSE if is_unsigned is TRUE)
+ *
+ * The caller provides a buffer for the string: that is the buf_end argument
+ * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
+ * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
+ */
+/*
+static char *
+     conv_10(register wide_int num, register bool_int is_unsigned,
+         register bool_int * is_negative, char *buf_end, register int *len)
+*/
+static char *conv_10(num, is_unsigned, is_negative, buf_end, len)
+register wide_int num;
+register bool_int is_unsigned;
+register bool_int *is_negative;
+char *buf_end;
+register int *len;
+{
+    register char *p = buf_end;
+    register u_wide_int magnitude;
+
+    if (is_unsigned) {
+       magnitude = (u_wide_int) num;
+       *is_negative = FALSE;
+    }
+    else {
+       *is_negative = (num < 0);
+
+       /*
+        * On a 2's complement machine, negating the most negative integer 
+        * results in a number that cannot be represented as a signed integer.
+        * Here is what we do to obtain the number's magnitude:
+        *      a. add 1 to the number
+        *      b. negate it (becomes positive)
+        *      c. convert it to unsigned
+        *      d. add 1
+        */
+       if (*is_negative) {
+           wide_int t = num + 1;
+
+           magnitude = ((u_wide_int) - t) + 1;
+       }
+       else
+           magnitude = (u_wide_int) num;
+    }
+
+    /*
+     * We use a do-while loop so that we write at least 1 digit 
+     */
+    do {
+       register u_wide_int new_magnitude = magnitude / 10;
+
+       *--p = magnitude - new_magnitude * 10 + '0';
+       magnitude = new_magnitude;
+    }
+    while (magnitude);
+
+    *len = buf_end - p;
+    return (p);
+}
+
+
+
+/*
+ * Convert a floating point number to a string formats 'f', 'e' or 'E'.
+ * The result is placed in buf, and len denotes the length of the string
+ * The sign is returned in the is_negative argument (and is not placed
+ * in buf).
+ */
+/*
+static char *
+     conv_fp(register char format, register double num,
+boolean_e add_dp, int precision, bool_int * is_negative, char *buf, int *len)
+*/
+static char *conv_fp(format, num, add_dp, precision, is_negative, buf, len)
+register char format;
+register double num;
+boolean_e add_dp;
+int precision;
+bool_int *is_negative;
+char *buf;
+int *len;
+{
+    register char *s = buf;
+    register char *p;
+    int decimal_point;
+
+    if (format == 'f')
+       p = ap_fcvt(num, precision, &decimal_point, is_negative);
+    else                       /* either e or E format */
+       p = ap_ecvt(num, precision + 1, &decimal_point, is_negative);
+
+    /*
+     * Check for Infinity and NaN
+     */
+    if (isalpha(*p)) {
+       *len = strlen(strcpy(buf, p));
+       *is_negative = FALSE;
+       return (buf);
+    }
+
+    if (format == 'f')
+       if (decimal_point <= 0) {
+           *s++ = '0';
+           if (precision > 0) {
+               *s++ = '.';
+               while (decimal_point++ < 0)
+                   *s++ = '0';
+           }
+           else if (add_dp)
+               *s++ = '.';
+       }
+       else {
+           while (decimal_point-- > 0)
+               *s++ = *p++;
+           if (precision > 0 || add_dp)
+               *s++ = '.';
+       }
+    else {
+       *s++ = *p++;
+       if (precision > 0 || add_dp)
+           *s++ = '.';
+    }
+
+    /*
+     * copy the rest of p, the NUL is NOT copied
+     */
+    while (*p)
+       *s++ = *p++;
+
+    if (format != 'f') {
+       char temp[EXPONENT_LENGTH];     /* for exponent conversion */
+       int t_len;
+       bool_int exponent_is_negative;
+
+       *s++ = format;          /* either e or E */
+       decimal_point--;
+       if (decimal_point != 0) {
+           p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative,
+                       &temp[EXPONENT_LENGTH], &t_len);
+           *s++ = exponent_is_negative ? '-' : '+';
+
+           /*
+            * Make sure the exponent has at least 2 digits
+            */
+           if (t_len == 1)
+               *s++ = '0';
+           while (t_len--)
+               *s++ = *p++;
+       }
+       else {
+           *s++ = '+';
+           *s++ = '0';
+           *s++ = '0';
+       }
+    }
+
+    *len = s - buf;
+    return (buf);
+}
+
+
+/*
+ * Convert num to a base X number where X is a power of 2. nbits determines X.
+ * For example, if nbits is 3, we do base 8 conversion
+ * Return value:
+ *      a pointer to a string containing the number
+ *
+ * The caller provides a buffer for the string: that is the buf_end argument
+ * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
+ * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
+ */
+/*
+static char *
+     conv_p2(register u_wide_int num, register int nbits,
+            char format, char *buf_end, register int *len)
+*/
+static char *conv_p2(num, nbits, format, buf_end, len)
+register u_wide_int num;
+register int nbits;
+char format;
+char *buf_end;
+register int *len;
+{
+    register int mask = (1 << nbits) - 1;
+    register char *p = buf_end;
+    static char low_digits[] = "0123456789abcdef";
+    static char upper_digits[] = "0123456789ABCDEF";
+    register char *digits = (format == 'X') ? upper_digits : low_digits;
+
+    do {
+       *--p = digits[num & mask];
+       num >>= nbits;
+    }
+    while (num);
+
+    *len = buf_end - p;
+    return (p);
+}
+
+
+/*
+ * Do format conversion placing the output in buffer
+ */
+/*
+static int format_converter(register buffy * odp, const char *fmt,
+                             va_list ap)
+*/
+static int format_converter(odp, fmt, ap)
+register buffy *odp;
+const char *fmt;
+va_list ap;
+{
+    register char *sp;
+    register char *bep;
+    register int cc = 0;
+    register int i;
+
+    register char *s = NULL;
+    char *q;
+    int s_len;
+
+    register int min_width = 0;
+    int precision = 0;
+    enum {
+       LEFT, RIGHT
+    } adjust;
+    char pad_char;
+    char prefix_char;
+
+    double fp_num;
+    wide_int i_num = (wide_int) 0;
+    u_wide_int ui_num;
+
+    char num_buf[NUM_BUF_SIZE];
+    char char_buf[2];          /* for printing %% and %<unknown> */
+
+    /*
+     * Flag variables
+     */
+    boolean_e is_long;
+    boolean_e alternate_form;
+    boolean_e print_sign;
+    boolean_e print_blank;
+    boolean_e adjust_precision;
+    boolean_e adjust_width;
+    bool_int is_negative;
+
+    sp = odp->nextb;
+    bep = odp->buf_end;
+
+    while (*fmt) {
+       if (*fmt != '%') {
+           INS_CHAR(*fmt, sp, bep, cc);
+       }
+       else {
+           /*
+            * Default variable settings
+            */
+           adjust = RIGHT;
+           alternate_form = print_sign = print_blank = NO;
+           pad_char = ' ';
+           prefix_char = NUL;
+
+           fmt++;
+
+           /*
+            * Try to avoid checking for flags, width or precision
+            */
+           if (isascii(*fmt) && !islower(*fmt)) {
+               /*
+                * Recognize flags: -, #, BLANK, +
+                */
+               for (;; fmt++) {
+                   if (*fmt == '-')
+                       adjust = LEFT;
+                   else if (*fmt == '+')
+                       print_sign = YES;
+                   else if (*fmt == '#')
+                       alternate_form = YES;
+                   else if (*fmt == ' ')
+                       print_blank = YES;
+                   else if (*fmt == '0')
+                       pad_char = '0';
+                   else
+                       break;
+               }
+
+               /*
+                * Check if a width was specified
+                */
+               if (isdigit(*fmt)) {
+                   STR_TO_DEC(fmt, min_width);
+                   adjust_width = YES;
+               }
+               else if (*fmt == '*') {
+                   min_width = arglist_val(ap, int);
+                   fmt++;
+                   adjust_width = YES;
+                   if (min_width < 0) {
+                       adjust = LEFT;
+                       min_width = -min_width;
+                   }
+               }
+               else
+                   adjust_width = NO;
+
+               /*
+                * Check if a precision was specified
+                *
+                * XXX: an unreasonable amount of precision may be specified
+                * resulting in overflow of num_buf. Currently we
+                * ignore this possibility.
+                */
+               if (*fmt == '.') {
+                   adjust_precision = YES;
+                   fmt++;
+                   if (isdigit(*fmt)) {
+                       STR_TO_DEC(fmt, precision);
+                   }
+                   else if (*fmt == '*') {
+                       precision = arglist_val(ap, int);
+                       fmt++;
+                       if (precision < 0)
+                           precision = 0;
+                   }
+                   else
+                       precision = 0;
+               }
+               else
+                   adjust_precision = NO;
+           }
+           else
+               adjust_precision = adjust_width = NO;
+
+           /*
+            * Modifier check
+            */
+           if (*fmt == 'l') {
+               is_long = YES;
+               fmt++;
+           }
+           else
+               is_long = NO;
+
+           /*
+            * Argument extraction and printing.
+            * First we determine the argument type.
+            * Then, we convert the argument to a string.
+            * On exit from the switch, s points to the string that
+            * must be printed, s_len has the length of the string
+            * The precision requirements, if any, are reflected in s_len.
+            *
+            * NOTE: pad_char may be set to '0' because of the 0 flag.
+            *   It is reset to ' ' by non-numeric formats
+            */
+           switch (*fmt) {
+           case 'u':
+               if (is_long)
+                   i_num = arglist_val(ap, u_wide_int);
+               else
+                   i_num = (wide_int) arglist_val(ap, unsigned int);
+               /*
+                * The rest also applies to other integer formats, so fall
+                * into that case.
+                */
+           case 'd':
+           case 'i':
+               /*
+                * Get the arg if we haven't already.
+                */
+               if ((*fmt) != 'u') {
+                   if (is_long)
+                       i_num = arglist_val(ap, wide_int);
+                   else
+                       i_num = (wide_int) arglist_val(ap, int);
+               };
+               s = conv_10(i_num, (*fmt) == 'u', &is_negative,
+                           &num_buf[NUM_BUF_SIZE], &s_len);
+               FIX_PRECISION(adjust_precision, precision, s, s_len);
+
+               if (*fmt != 'u') {
+                   if (is_negative)
+                       prefix_char = '-';
+                   else if (print_sign)
+                       prefix_char = '+';
+                   else if (print_blank)
+                       prefix_char = ' ';
+               }
+               break;
+
+
+           case 'o':
+               if (is_long)
+                   ui_num = arglist_val(ap, u_wide_int);
+               else
+                   ui_num = (u_wide_int) arglist_val(ap, unsigned int);
+               s = conv_p2(ui_num, 3, *fmt,
+                           &num_buf[NUM_BUF_SIZE], &s_len);
+               FIX_PRECISION(adjust_precision, precision, s, s_len);
+               if (alternate_form && *s != '0') {
+                   *--s = '0';
+                   s_len++;
+               }
+               break;
+
+
+           case 'x':
+           case 'X':
+               if (is_long)
+                   ui_num = (u_wide_int) arglist_val(ap, u_wide_int);
+               else
+                   ui_num = (u_wide_int) arglist_val(ap, unsigned int);
+               s = conv_p2(ui_num, 4, *fmt,
+                           &num_buf[NUM_BUF_SIZE], &s_len);
+               FIX_PRECISION(adjust_precision, precision, s, s_len);
+               if (alternate_form && i_num != 0) {
+                   *--s = *fmt;        /* 'x' or 'X' */
+                   *--s = '0';
+                   s_len += 2;
+               }
+               break;
+
+
+           case 's':
+               s = arglist_val(ap, char *);
+               if (s != NULL) {
+                   s_len = strlen(s);
+                   if (adjust_precision && precision < s_len)
+                       s_len = precision;
+               }
+               else {
+                   s = S_NULL;
+                   s_len = S_NULL_LEN;
+               }
+               pad_char = ' ';
+               break;
+
+
+           case 'f':
+           case 'e':
+           case 'E':
+               fp_num = arglist_val(ap, double);
+
+               s = conv_fp(*fmt, fp_num, alternate_form,
+                       (adjust_precision == NO) ? FLOAT_DIGITS : precision,
+                           &is_negative, &num_buf[1], &s_len);
+               if (is_negative)
+                   prefix_char = '-';
+               else if (print_sign)
+                   prefix_char = '+';
+               else if (print_blank)
+                   prefix_char = ' ';
+               break;
+
+
+           case 'g':
+           case 'G':
+               if (adjust_precision == NO)
+                   precision = FLOAT_DIGITS;
+               else if (precision == 0)
+                   precision = 1;
+               /*
+                * * We use &num_buf[ 1 ], so that we have room for the sign
+                */
+               s = ap_gcvt(arglist_val(ap, double), precision, &num_buf[1]);
+               if (*s == '-')
+                   prefix_char = *s++;
+               else if (print_sign)
+                   prefix_char = '+';
+               else if (print_blank)
+                   prefix_char = ' ';
+
+               s_len = strlen(s);
+
+               if (alternate_form && (q = strchr(s, '.')) == NULL)
+                   s[s_len++] = '.';
+               if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
+                   *q = 'E';
+               break;
+
+
+           case 'c':
+               char_buf[0] = (char) (arglist_val(ap, int));
+               s = &char_buf[0];
+               s_len = 1;
+               pad_char = ' ';
+               break;
+
+
+           case '%':
+               char_buf[0] = '%';
+               s = &char_buf[0];
+               s_len = 1;
+               pad_char = ' ';
+               break;
+
+
+           case 'n':
+               *(arglist_val(ap, int *)) = cc;
+               break;
+
+               /*
+                * Always extract the argument as a "char *" pointer. We 
+                * should be using "void *" but there are still machines 
+                * that don't understand it.
+                * If the pointer size is equal to the size of an unsigned
+                * integer we convert the pointer to a hex number, otherwise 
+                * we print "%p" to indicate that we don't handle "%p".
+                */
+           case 'p':
+               ui_num = (u_wide_int) arglist_val(ap, char *);
+
+               if (sizeof(char *) <= sizeof(u_wide_int))
+                        s = conv_p2(ui_num, 4, 'x',
+                                    &num_buf[NUM_BUF_SIZE], &s_len);
+               else {
+                   s = "%p";
+                   s_len = 2;
+               }
+               pad_char = ' ';
+               break;
+
+
+           case NUL:
+               /*
+                * The last character of the format string was %.
+                * We ignore it.
+                */
+               continue;
+
+
+               /*
+                * The default case is for unrecognized %'s.
+                * We print %<char> to help the user identify what
+                * option is not understood.
+                * This is also useful in case the user wants to pass
+                * the output of format_converter to another function
+                * that understands some other %<char> (like syslog).
+                * Note that we can't point s inside fmt because the
+                * unknown <char> could be preceded by width etc.
+                */
+           default:
+               char_buf[0] = '%';
+               char_buf[1] = *fmt;
+               s = char_buf;
+               s_len = 2;
+               pad_char = ' ';
+               break;
+           }
+
+           if (prefix_char != NUL) {
+               *--s = prefix_char;
+               s_len++;
+           }
+
+           if (adjust_width && adjust == RIGHT && min_width > s_len) {
+               if (pad_char == '0' && prefix_char != NUL) {
+                   INS_CHAR(*s, sp, bep, cc)
+                       s++;
+                   s_len--;
+                   min_width--;
+               }
+               PAD(min_width, s_len, pad_char);
+           }
+
+           /*
+            * Print the string s. 
+            */
+           for (i = s_len; i != 0; i--) {
+               INS_CHAR(*s, sp, bep, cc);
+               s++;
+           }
+
+           if (adjust_width && adjust == LEFT && min_width > s_len)
+               PAD(min_width, s_len, pad_char);
+       }
+       fmt++;
+    }
+    odp->nextb = sp;
+    return (cc);
+}
+
+
+/*
+ * This is the general purpose conversion function.
+ */
+/*
+static void strx_printv(int *ccp, char *buf, size_t len, const char *format,
+                       va_list ap)
+*/
+static void strx_printv(ccp, buf, len, format, ap)
+int *ccp;
+char *buf;
+size_t len;
+const char *format;
+va_list ap;
+{
+    buffy od;
+    int cc;
+
+    /*
+     * First initialize the descriptor
+     * Notice that if no length is given, we initialize buf_end to the
+     * highest possible address.
+     */
+    od.buf_end = len ? &buf[len] : (char *) ~0;
+    od.nextb = buf;
+
+    /*
+     * Do the conversion
+     */
+    cc = format_converter(&od, format, ap);
+    if (len == 0 || od.nextb <= od.buf_end)
+       *(od.nextb) = '\0';
+    if (ccp)
+       *ccp = cc;
+}
+
+
+/*
+int ap_snprintf(char *buf, size_t len, const char *format,...)
+*/
+printf_arglist_function2(int ap_snprintf,
+                        char *, buf,
+                        size_t, len,
+                        const char *, format)
+{
+    int cc;
+    va_list ap;
+
+    arglist_start(ap, format);
+    strx_printv(&cc, buf, (len - 1), format, ap);
+    arglist_end(ap);
+    return (cc);
+}
+
+
+/*
+int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap)
+*/
+int ap_vsnprintf(buf, len, format, ap)
+char *buf;
+size_t len;
+const char *format;
+va_list ap;
+{
+    int cc;
+
+    strx_printv(&cc, buf, (len - 1), format, ap);
+    return (cc);
+}
+
+#endif /* HAVE_SNPRINTF */
diff --git a/common-src/statfs.c b/common-src/statfs.c
new file mode 100644 (file)
index 0000000..c2b9bd9
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * 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: statfs.c,v 1.10.4.1 1999/05/23 17:11:18 oliva Exp $
+ *
+ * a generic statfs-like routine
+ */
+#include "amanda.h"
+#include "statfs.h"
+
+/*
+ * You are in a maze of twisty passages, all alike.
+ * Begin retching now.
+ */
+
+#ifdef STATFS_ULTRIX
+# include <sys/param.h>
+# include <sys/mount.h>
+# define STATFS_STRUCT struct fs_data
+# define STATFS_TOTAL(buf)     (buf).fd_btot
+# define STATFS_AVAIL(buf)     (buf).fd_bfreen
+# define STATFS_FREE(buf)      (buf).fd_bfree
+# define STATFS_FILES(buf)     (buf).fd_gtot
+# define STATFS_FAVAIL(buf)    (buf).fd_gfree
+# define STATFS_FFREE(buf)     (buf).fd_gfree
+# define STATFS_SCALE(buf)     1024
+# define STATFS(path, buffer)  statfs(path, &buffer)
+#else
+# if defined(HAVE_SYS_STATVFS_H) && !defined(STATFS_SCO_OS5)
+/*
+** System V.4 (STATFS_SVR4)
+*/
+#  include <sys/statvfs.h>
+#  define STATFS_TYP           "SVR4 (Irix-5+, Solaris-2, Linux glibc 2.1)"
+#  define STATFS_STRUCT        struct statvfs
+#  define STATFS_TOTAL(buf)    (buf).f_blocks
+#  define STATFS_AVAIL(buf)    (buf).f_bavail
+#  define STATFS_FREE(buf)     (buf).f_bfree
+#  define STATFS_FILES(buf)    (buf).f_files
+#  define STATFS_FAVAIL(buf)   (buf).f_favail
+#  define STATFS_FFREE(buf)    (buf).f_ffree
+#  define STATFS_SCALE(buf)    ((buf).f_frsize?(buf).f_frsize:(buf).f_bsize)
+#  define STATFS(path, buffer) statvfs(path, &buffer)
+# else
+#  if HAVE_SYS_VFS_H
+/*
+** (STATFS_AIX, STATFS_VFS, STATFS_NEXT)
+*/
+#   ifdef HAVE_SYS_STATFS_H /* AIX */
+#    include <sys/statfs.h>
+#   endif
+#   include <sys/vfs.h>
+#   define STATFS_TYP          "Posix (NeXTstep, AIX, Linux, HP-UX)"
+#   define STATFS_STRUCT       struct statfs
+#   define STATFS_TOTAL(buf)   (buf).f_blocks
+#   define STATFS_AVAIL(buf)   (buf).f_bavail
+#   define STATFS_FREE(buf)    (buf).f_bfree
+#   define STATFS_FILES(buf)   (buf).f_files
+#   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)
+#  else
+#   if HAVE_SYS_STATFS_H
+/*
+** System V.3 (STATFS_SVR3)
+*/
+#    include <sys/statfs.h>
+#    define STATFS_TYP         "SVR3 (Irix-3, Irix-4)"
+#    define STATFS_STRUCT      struct statfs
+#    define STATFS_TOTAL(buf)  (buf).f_blocks
+#    define STATFS_AVAIL(buf)  (buf).f_bfree
+#    define STATFS_FREE(buf)   (buf).f_bfree
+#    define STATFS_FILES(buf)  (buf).f_files
+#    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)
+#   else
+#    if HAVE_SYS_MOUNT_H
+/*
+** BSD (STATFS_BSD43, STATFS_BSD44)
+*/
+#     ifdef HAVE_SYS_PARAM_H /* BSD-4.4 */
+#      include <sys/param.h>
+#     endif
+#     include <sys/mount.h>
+#     define STATFS_TYP                "BSD43/44"
+#     define STATFS_STRUCT     struct statfs
+#     define STATFS_TOTAL(buf) (buf).f_blocks
+#     define STATFS_AVAIL(buf) (buf).f_bavail
+#     define STATFS_FREE(buf)  (buf).f_bfree
+#     define STATFS_FILES(buf) (buf).f_files
+#     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)
+#     ifdef STATFS_OSF1
+#      define STATFS(path, buffer)     statfs(path, &buffer, sizeof(STATFS_STRUCT))
+#     endif
+#    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;
+{
+    STATFS_STRUCT statbuf;
+
+    if(STATFS(dir, statbuf) == -1)
+       return -1;
+
+    /* 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));
+
+    /* inode stats */
+
+    sp->files  = STATFS_FILES(statbuf);
+    sp->favail = STATFS_FAVAIL(statbuf);
+    sp->ffree  = STATFS_FFREE(statbuf);
+
+    return 0;
+}
+
+#ifdef TEST
+/* ----- test scaffolding ----- */
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    generic_fs_stats_t statbuf;
+    int fd;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname(argv[0]);
+
+    if(argc < 2) {
+       fprintf(stderr, "Usage: %s files ...\n", get_pname());
+       return 1;
+    }
+
+    printf("statfs (%s)\n",STATFS_TYP);
+    printf(
+"name                             total    free   avail  files  ffree favail\n"
+          );
+    printf(
+"------------------------------ ------- ------- ------- ------ ------ ------\n"
+          );
+
+    do {
+       argc--,argv++;
+       if(get_fs_stats(*argv, &statbuf) == -1) {
+           perror(*argv);
+           continue;
+       }
+       printf("%-30.30s %7ld %7ld %7ld %6ld %6ld %6ld\n", *argv,
+              statbuf.total, statbuf.free, statbuf.avail,
+              statbuf.files, statbuf.ffree, statbuf.favail);
+    } while(argc > 1);
+    return 0;
+}
+#endif
diff --git a/common-src/statfs.h b/common-src/statfs.h
new file mode 100644 (file)
index 0000000..8260d6c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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: statfs.h,v 1.3 1998/07/04 00:18:58 oliva Exp $
+ *
+ * interface to statfs module
+ */
+#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 */
+
+    long files;                /* total # of files in filesystem */
+    long favail;       /* # files avail for non-superuser */
+    long ffree;                /* # files free for superuser */
+} generic_fs_stats_t;
+
+int get_fs_stats P((char *dir, generic_fs_stats_t *sp));
diff --git a/common-src/strcasecmp.c b/common-src/strcasecmp.c
new file mode 100644 (file)
index 0000000..b3dd1fa
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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
+
+/* 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;
+{
+  register const unsigned char *p1 = (const unsigned char *) s1;
+  register const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2)
+    return 0;
+
+  do
+    {
+      c1 = tolower (*p1++);
+      c2 = tolower (*p2++);
+      if (c1 == '\0' || c2 == '\0' || c1 != c2)
+        return c1 - c2;
+    } while ( 1 == 1 );
+}
diff --git a/common-src/stream.c b/common-src/stream.c
new file mode 100644 (file)
index 0000000..5fdc52a
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: stream.c,v 1.10.2.6.4.4.2.4 2002/11/12 19:19:03 martinea Exp $
+ *
+ * functions for managing stream sockets
+ */
+#include "amanda.h"
+#include "dgram.h"
+#include "stream.h"
+#include "clock.h"
+#include "util.h"
+
+/* local functions */
+static void try_socksize P((int sock, int which, int size));
+
+int stream_server(portp, sendsize, recvsize)
+int *portp;
+int sendsize, recvsize;
+{
+    int server_socket;
+    socklen_t len;
+#ifdef SO_KEEPALIVE
+    int on = 1;
+    int r;
+#endif
+    struct sockaddr_in server;
+    int save_errno;
+
+    *portp = -1;                               /* 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",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       errno = save_errno;
+       return -1;
+    }
+    if(server_socket < 0 || server_socket >= FD_SETSIZE) {
+       aclose(server_socket);
+       errno = EMFILE;                         /* out of range */
+       save_errno = errno;
+       dbprintf(("%s: stream_server: socket out of range: %d\n",
+                 debug_prefix(NULL),
+                 server_socket));
+       errno = save_errno;
+       return -1;
+    }
+    memset(&server, 0, sizeof(server));
+    server.sin_family = 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);
+
+    /*
+     * 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
+     * fails, we just go for any port.
+     *
+     * It is up to the caller to make sure we have the proper permissions
+     * to get the desired port, and to make sure we return a port that
+     * is within the range it requires.
+     */
+#ifdef TCPPORTRANGE
+    if (bind_portrange(server_socket, &server, TCPPORTRANGE) == 0)
+       goto out;
+#endif
+
+    if (bind_portrange(server_socket, &server, 512, IPPORT_RESERVED - 1) == 0)
+       goto out;
+
+    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",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       aclose(server_socket);
+       errno = save_errno;
+       return -1;
+    }
+
+out:
+    listen(server_socket, 1);
+
+    /* find out what port was actually used */
+
+    len = sizeof(server);
+    if(getsockname(server_socket, (struct sockaddr *)&server, &len) == -1) {
+       save_errno = errno;
+       dbprintf(("%s: stream_server: getsockname() failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+       aclose(server_socket);
+       errno = save_errno;
+       return -1;
+    }
+
+#ifdef SO_KEEPALIVE
+    r = setsockopt(server_socket, SOL_SOCKET, SO_KEEPALIVE,
+       (void *)&on, (socklen_t)sizeof(on));
+    if(r == -1) {
+       save_errno = errno;
+       dbprintf(("%s: stream_server: setsockopt(SO_KEEPALIVE) failed: %s\n",
+                 debug_prefix(NULL),
+                 strerror(save_errno)));
+        aclose(server_socket);
+       errno = save_errno;
+        return -1;
+    }
+#endif
+
+    *portp = (int) ntohs(server.sin_port);
+    dbprintf(("%s: stream_server: waiting for connection: %s.%d\n",
+             debug_prefix_time(NULL),
+             inet_ntoa(server.sin_addr),
+             *portp));
+    return server_socket;
+}
+
+static int
+stream_client_internal(hostname, port, sendsize, recvsize, localport, priv)
+    char *hostname;
+    int port, sendsize, recvsize, *localport, priv;
+{
+    int client_socket, len;
+#ifdef SO_KEEPALIVE
+    int on = 1;
+    int r;
+#endif
+    struct sockaddr_in svaddr, claddr;
+    struct hostent *hostp;
+    int save_errno;
+    char *f;
+
+    f = priv ? "stream_client_privileged" : "stream_client";
+
+    if((hostp = gethostbyname(hostname)) == NULL) {
+       save_errno = errno;
+       dbprintf(("%s: %s: gethostbyname(%s) failed\n",
+                 debug_prefix(NULL),
+                 f,
+                 hostname));
+       errno = save_errno;
+       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);
+
+    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;
+    claddr.sin_addr.s_addr = INADDR_ANY;
+
+    /*
+     * If a privileged port range was requested, we try to get a port in
+     * that range first and fail if it is not available.  Next, we try
+     * to get a port in the range built in when Amanda was configured.
+     * If that fails, we just go for any port.
+     *
+     * It is up to the caller to make sure we have the proper permissions
+     * to get the desired port, and to make sure we return a port that
+     * is within the range it requires.
+     */
+    if (priv) {
+       int b;
+
+       b = bind_portrange(client_socket, &claddr, 512, IPPORT_RESERVED - 1);
+       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 TCPPORTRANGE
+    if (bind_portrange(client_socket, &claddr, TCPPORTRANGE) == 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;
+    }
+
+    if(connect(client_socket, (struct sockaddr *)&svaddr, sizeof(svaddr))
+       == -1) {
+       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;
+    }
+
+    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);
+
+    if (localport != NULL)
+       *localport = ntohs(claddr.sin_port);
+
+    return client_socket;
+}
+
+int
+stream_client_privileged(hostname, port, sendsize, recvsize, localport)
+    char *hostname;
+    int port, sendsize, recvsize, *localport;
+{
+    return stream_client_internal(hostname,
+                                 port,
+                                 sendsize,
+                                 recvsize,
+                                 localport,
+                                 1);
+}
+
+int
+stream_client(hostname, port, sendsize, recvsize, localport)
+    char *hostname;
+    int port, sendsize, recvsize, *localport;
+{
+    return stream_client_internal(hostname,
+                                 port,
+                                 sendsize,
+                                 recvsize,
+                                 localport,
+                                 0);
+}
+
+/* don't care about these values */
+static struct sockaddr_in addr;
+static int addrlen;
+
+int stream_accept(server_socket, timeout, sendsize, recvsize)
+int server_socket, timeout, sendsize, recvsize;
+{
+    fd_set readset;
+    struct timeval tv;
+    int nfound, connected_socket;
+    int save_errno;
+
+    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",
+                     debug_prefix_time(NULL),
+                     strerror(save_errno)));
+       } 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",
+                             debug_prefix_time(NULL),
+                             i,
+                             server_socket));
+               }
+           }
+           save_errno = EBADF;
+       }
+       errno = save_errno;
+       return -1;
+    }
+
+    while(1) {
+       addrlen = 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;
+       }
+       dbprintf(("%s: stream_accept: connection from %s.%d\n",
+                 debug_prefix_time(NULL),
+                 inet_ntoa(addr.sin_addr),
+                 ntohs(addr.sin_port)));
+       /*
+        * 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 != AF_INET) {
+           dbprintf(("%s: family is %d instead of %d(AF_INET): ignored\n",
+                     debug_prefix_time(NULL),
+                     addr.sin_family,
+                     AF_INET));
+       }
+       if(ntohs(addr.sin_port) == 20) {
+           dbprintf(("%s: remote port is %d: ignored\n",
+                     debug_prefix_time(NULL),
+                     ntohs(addr.sin_port)));
+       }
+       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;
+}
+
+static void try_socksize(sock, which, size)
+int sock, which, size;
+{
+    int origsize;
+
+    origsize = size;
+    /* keep trying, get as big a buffer as possible */
+    while(size > 1024 &&
+         setsockopt(sock, SOL_SOCKET, which, (void *) &size, sizeof(int)) < 0)
+       size -= 1024;
+    if(size > 1024) {
+       dbprintf(("%s: try_socksize: %s buffer size is %d\n",
+                 debug_prefix(NULL),
+                 (which == SO_SNDBUF) ? "send" : "receive",
+                 size));
+    } else {
+       dbprintf(("%s: try_socksize: could not allocate %s buffer of %d\n",
+                 debug_prefix(NULL),
+                 (which == SO_SNDBUF) ? "send" : "receive",
+                 origsize));
+    }
+}
diff --git a/common-src/stream.h b/common-src/stream.h
new file mode 100644 (file)
index 0000000..2253828
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: stream.h,v 1.4.2.1.4.3 2001/08/14 22:20:57 jrjackson Exp $
+ *
+ * interface to stream module
+ */
+#ifndef STREAM_H
+#define STREAM_H
+
+#include "amanda.h"
+
+/* Note: This must be kept in sync with the DATABUF_SIZE defined in
+ * client-src/sendbackup-krb4.c, or kerberos encryption won't work...
+ *     - Chris Ross (cross@uu.net)  4-Jun-1998
+ */
+#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((char *hostname,
+                               int port,
+                               int sendsize,
+                               int recvsize,
+                               int *localport));
+int stream_client P((char *hostname,
+                    int port,
+                    int sendsize,
+                    int recvsize,
+                    int *localport));
+
+#endif
diff --git a/common-src/strerror.c b/common-src/strerror.c
new file mode 100644 (file)
index 0000000..96bb4d7
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* $Id: strerror.c,v 1.4 1997/12/30 05:24:24 jrj Exp $ */
+
+#include "amanda.h"
+
+/*
+ * Return the error message corresponding to some error number.
+ */
+char *
+strerror(e)
+       int e;
+{
+       extern int sys_nerr;
+       extern char *sys_errlist[];
+       char number[NUM_STR_SIZE];
+       static char *unknown = NULL;
+
+       if ((unsigned)e < sys_nerr)
+               return sys_errlist[e];
+       ap_snprintf(number, sizeof(number), "%d", e);
+       unknown = newstralloc2(unknown, "Unknown error: ", number);
+       return unknown;
+}
diff --git a/common-src/strftime.c b/common-src/strftime.c
new file mode 100644 (file)
index 0000000..e3b0ea7
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that: (1) source distributions retain this entire copyright
+ * notice and comment, and (2) distributions including binaries display
+ * the following acknowledgement:  ``This product includes software
+ * developed by the University of California, Berkeley and its contributors''
+ * in the documentation or other materials provided with the distribution
+ * and in all advertising materials mentioning features or use of this
+ * software. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+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>
+#include <tzfile.h>
+#include <string.h>
+
+static char *afmt[] = {
+       "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
+};
+static char *Afmt[] = {
+       "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
+       "Saturday",
+};
+static char *bfmt[] = {
+       "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
+       "Oct", "Nov", "Dec",
+};
+static char *Bfmt[] = {
+       "January", "February", "March", "April", "May", "June", "July",
+       "August", "September", "October", "November", "December",
+};
+
+static size_t gsize;
+static char *pt;
+
+size_t
+strftime(s, maxsize, format, t)
+       char *s;
+       char *format;
+       size_t maxsize;
+       struct tm *t;
+{
+       size_t _fmt();
+
+       pt = s;
+       if ((gsize = maxsize) < 1)
+               return(0);
+       if (_fmt(format, t)) {
+               *pt = '\0';
+               return(maxsize - gsize);
+       }
+       return(0);
+}
+
+static size_t
+_fmt(format, t)
+       register char *format;
+       struct tm *t;
+{
+       for (; *format; ++format) {
+               if (*format == '%')
+                       switch(*++format) {
+                       case '\0':
+                               --format;
+                               break;
+                       case 'A':
+                               if (t->tm_wday < 0 || t->tm_wday > 6)
+                                       return(0);
+                               if (!_add(Afmt[t->tm_wday]))
+                                       return(0);
+                               continue;
+                       case 'a':
+                               if (t->tm_wday < 0 || t->tm_wday > 6)
+                                       return(0);
+                               if (!_add(afmt[t->tm_wday]))
+                                       return(0);
+                               continue;
+                       case 'B':
+                               if (t->tm_mon < 0 || t->tm_mon > 11)
+                                       return(0);
+                               if (!_add(Bfmt[t->tm_mon]))
+                                       return(0);
+                               continue;
+                       case 'b':
+                       case 'h':
+                               if (t->tm_mon < 0 || t->tm_mon > 11)
+                                       return(0);
+                               if (!_add(bfmt[t->tm_mon]))
+                                       return(0);
+                               continue;
+                       case 'C':
+                               if (!_fmt("%a %b %e %H:%M:%S %Y", t))
+                                       return(0);
+                               continue;
+                       case 'c':
+                               if (!_fmt("%m/%d/%y %H:%M:%S", t))
+                                       return(0);
+                               continue;
+                       case 'e':
+                               if (!_conv(t->tm_mday, 2, ' '))
+                                       return(0);
+                               continue;
+                       case 'D':
+                               if (!_fmt("%m/%d/%y", t))
+                                       return(0);
+                               continue;
+                       case 'd':
+                               if (!_conv(t->tm_mday, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'H':
+                               if (!_conv(t->tm_hour, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'I':
+                               if (!_conv(t->tm_hour % 12 ?
+                                   t->tm_hour % 12 : 12, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'j':
+                               if (!_conv(t->tm_yday + 1, 3, '0'))
+                                       return(0);
+                               continue;
+                       case 'k':
+                               if (!_conv(t->tm_hour, 2, ' '))
+                                       return(0);
+                               continue;
+                       case 'l':
+                               if (!_conv(t->tm_hour % 12 ?
+                                   t->tm_hour % 12 : 12, 2, ' '))
+                                       return(0);
+                               continue;
+                       case 'M':
+                               if (!_conv(t->tm_min, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'm':
+                               if (!_conv(t->tm_mon + 1, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'n':
+                               if (!_add("\n"))
+                                       return(0);
+                               continue;
+                       case 'p':
+                               if (!_add(t->tm_hour >= 12 ? "PM" : "AM"))
+                                       return(0);
+                               continue;
+                       case 'R':
+                               if (!_fmt("%H:%M", t))
+                                       return(0);
+                               continue;
+                       case 'r':
+                               if (!_fmt("%I:%M:%S %p", t))
+                                       return(0);
+                               continue;
+                       case 'S':
+                               if (!_conv(t->tm_sec, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'T':
+                       case 'X':
+                               if (!_fmt("%H:%M:%S", t))
+                                       return(0);
+                               continue;
+                       case 't':
+                               if (!_add("\t"))
+                                       return(0);
+                               continue;
+                       case 'U':
+                               if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7,
+                                   2, '0'))
+                                       return(0);
+                               continue;
+                       case 'W':
+                               if (!_conv((t->tm_yday + 7 -
+                                   (t->tm_wday ? (t->tm_wday - 1) : 6))
+                                   / 7, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'w':
+                               if (!_conv(t->tm_wday, 1, '0'))
+                                       return(0);
+                               continue;
+                       case 'x':
+                               if (!_fmt("%m/%d/%y", t))
+                                       return(0);
+                               continue;
+                       case 'y':
+                               if (!_conv((t->tm_year + TM_YEAR_BASE)
+                                   % 100, 2, '0'))
+                                       return(0);
+                               continue;
+                       case 'Y':
+                               if (!_conv(t->tm_year + TM_YEAR_BASE, 4, '0'))
+                                       return(0);
+                               continue;
+                       case 'Z':
+                               if (!t->tm_zone || !_add(t->tm_zone))
+                                       return(0);
+                               continue;
+                       case '%':
+                       /*
+                        * X311J/88-090 (4.12.3.5): if conversion char is
+                        * undefined, behavior is undefined.  Print out the
+                        * character itself as printf(3) does.
+                        */
+                       default:
+                               break;
+               }
+               if (!gsize--)
+                       return(0);
+               *pt++ = *format;
+       }
+       return(gsize);
+}
+
+static
+_conv(n, digits, pad)
+       int n, digits;
+       char pad;
+{
+       static char buf[10];
+       register char *p;
+
+       for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
+               *p-- = n % 10 + '0';
+       while (p > buf && digits-- > 0)
+               *p-- = pad;
+       return(_add(++p));
+}
+
+static
+_add(str)
+       register char *str;
+{
+       for (;; ++pt, --gsize) {
+               if (!gsize)
+                       return(0);
+               if (!(*pt = *str++))
+                       return(1);
+       }
+}
diff --git a/common-src/strncasecmp.c b/common-src/strncasecmp.c
new file mode 100644 (file)
index 0000000..3bcbb94
--- /dev/null
@@ -0,0 +1,50 @@
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+/*
+ * The following function compares the first 'n' characters in 's1'
+ * and 's2' without considering case. It returns less than, equal to
+ * or greater than zero if 's1' is lexicographically less than, equal
+ * to or greater than 's2'.
+ */
+
+int
+strncasecmp(s1, s2, n)
+      const char *s1;
+      const char *s2;
+      size_t n;
+{
+  unsigned char c1, c2;
+
+  if ( (s1 == s2 ) || (n == 0) ) 
+  {
+      /*
+       * the arguments are identical or there are no characters to be
+       * compared
+       */
+      return 0;
+  }
+
+  while (n > 0)
+  {
+      c1 = (unsigned char)tolower(*s1++);
+      c2 = (unsigned char)tolower(*s2++);
+
+      if (c1 != c2)
+      {
+         return(c1 - c2);
+      }
+
+      n--;
+  }
+
+  return(0);
+}
diff --git a/common-src/strstr.c b/common-src/strstr.c
new file mode 100644 (file)
index 0000000..4882c39
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: strstr.c,v 1.4.10.1 2002/02/11 01:30:42 jrjackson Exp $
+ *
+ * replacement for missing ANSI-C strstr function
+ */
+#include "amanda.h"
+
+char *strstr(a, b)
+char *a, *b;
+{
+        size_t alen, blen, i;
+
+        alen = strlen(a);
+        blen = strlen(b);
+
+        for(i=0; i <= alen-blen; i++, a++)
+            if(strncmp(a, b, blen) == 0) return a;
+
+        return NULL;
+}
diff --git a/common-src/token.c b/common-src/token.c
new file mode 100644 (file)
index 0000000..c56c9d1
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1997-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: token.c,v 1.22.8.3 2003/10/22 17:32:33 kovert Exp $
+ *
+ * token bashing routines
+ */
+
+/*
+** The quoting method used here was selected because it has the
+** property that quoting a string that doesn't contain funny
+** characters results in an unchanged string and it was easy to code.
+** There are probably other algorithms that are just as effective.
+**/
+
+#include "amanda.h"
+#include "arglist.h"
+#include "token.h"
+
+/* Split a string up into tokens.
+** There is exactly one separator character between tokens.
+** XXX Won't work too well if separator is '\'!
+**
+** 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 " " */
+{
+    register char *pi, *po;
+    register int fld;
+    register size_t len;
+    static char *buf = (char *)0; /* XXX - static buffer */
+    int in_quotes;
+
+    assert(str && token && toklen > 0 && sep);
+
+    token[0] = str;
+
+    for (fld = 1; fld < toklen; fld++) token[fld] = (char *)0;
+
+    fld = 0;
+
+    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++;
+       }
+    }
+
+    /* Allocate some space */
+
+    buf = newalloc(buf, len+1);
+
+    /* Copy it across and tokenise it */
+
+    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 */
+           *po = '\0'; /* end of token */
+           if (fld+1 >= toklen) return fld; /* too many tokens */
+           token[++fld] = po + 1;
+           po++;
+       }
+       else {
+           *po++ = *pi;        /* normal */
+       }
+    }
+    *po = '\0';
+
+    assert(po == buf + len);   /* Just checking! */
+
+    return fld;
+}
+
+/*
+** Quote all the funny characters in one token.
+** - squotef - formatted string with space separator
+** - quotef  - formatted string with specified separators
+** - squote  - fixed string with space separator
+** - quote   - fixed strings with specified separators
+**/
+printf_arglist_function(char *squotef, char *, format)
+{
+       va_list argp;
+       char linebuf[16384];
+
+       /* Format the token */
+
+       arglist_start(argp, format);
+       ap_vsnprintf(linebuf, sizeof(linebuf), format, argp);
+       arglist_end(argp);
+
+       return quote(" ", linebuf);
+}
+
+printf_arglist_function1(char *quotef, char *, sep, char *, format)
+{
+       va_list argp;
+       char linebuf[16384];
+
+       /* Format the token */
+
+       arglist_start(argp, format);
+       ap_vsnprintf(linebuf, sizeof(linebuf), format, argp);
+       arglist_end(argp);
+
+       return quote(sep, linebuf);
+}
+
+char *squote(str)
+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 */
+{
+    register char *pi, *po;
+    register size_t len;
+    char *buf;
+    int sep, need_quotes;
+
+    /* Calculate the length of the quoted token. */
+
+    len = sep = 0;
+    for (pi = str; *pi; pi++) {
+       if (*pi < ' ' || *pi > '~')
+           len = len + 4;
+       else if (*pi == '\\' || *pi == '"')
+           len = len + 2;
+       else if (*sepchr && strchr(sepchr, *pi)) {
+           len = len + 1;
+           sep++;
+       }
+       else
+           len++;
+    }
+
+    need_quotes = (sep != 0);
+
+    if (need_quotes) len = len + 2;
+
+    /* Allocate some space */
+
+    buf = alloc(len+1);                /* trailing null */
+
+    /* Copy it across */
+
+    po = buf;
+
+    if (need_quotes) *po++ = '"';
+
+    for (pi = str; *pi; pi++) {
+       if (*pi < ' ' || *pi > '~') {
+           *po++ = '\\';
+           *po++ = ((*pi >> 6) & 07) + '0';
+           *po++ = ((*pi >> 3) & 07) + '0';
+           *po++ = ((*pi     ) & 07) + '0';
+       }
+       else if (*pi == '\\' || *pi == '"') {
+           *po++ = '\\';
+           *po++ = *pi;
+       }
+       else *po++ = *pi;
+    }
+
+    if (need_quotes) *po++ = '"';
+
+    *po = '\0';
+
+    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 *pi, *po;
+    size_t len;
+    char *buf;
+
+    /* Calculate the length of the quoted token. */
+
+    len = 0;
+    for (pi = str; *pi; pi++) {
+       switch (*pi) {
+           /* regular expression meta-characters: */
+#define META_CHARS \
+       case '\\': \
+       case '.': \
+       case '?': \
+       case '*': \
+       case '+': \
+       case '^': \
+       case '$': \
+       case '|': \
+       case '(': \
+       case ')': \
+       case '[': \
+       case ']': \
+       case '{': \
+       case '}' /* no colon */
+       META_CHARS:
+           len++;
+           /* fall through */
+       default:
+           len++;
+           break;
+       }
+    }
+
+    /* Allocate some space */
+
+    buf = alloc(len+1);                /* trailing null */
+
+    /* Copy it across */
+
+    po = buf;
+
+    for (pi = str; *pi; pi++) {
+       switch (*pi) {
+       META_CHARS:
+#undef META_CHARS
+           *po++ = '\\';
+           /* fall through */
+       default:
+           *po++ = *pi;
+           break;
+       }
+    }
+
+    *po = '\0';
+
+    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 *pi, *po;
+    size_t len;
+    char *buf;
+
+    /* Calculate the length of the quoted token. */
+
+    len = 0;
+    for (pi = str; *pi; pi++) {
+       switch (*pi) {
+           /* shell meta-characters: */
+#define META_CHARS \
+       case '\\': \
+       case ' ': \
+       case '\t': \
+       case '\n': \
+       case '?': \
+       case '*': \
+       case '$': \
+       case '~': \
+       case '!': \
+       case ';': \
+       case '&': \
+       case '<': \
+       case '>': \
+       case '\'': \
+       case '\"': \
+       case '`': \
+       case '|': \
+       case '(': \
+       case ')': \
+       case '[': \
+       case ']': \
+       case '{': \
+       case '}' /* no colon */
+       META_CHARS:
+           len++;
+           /* fall through */
+       default:
+           len++;
+           break;
+       }
+    }
+
+    /* Allocate some space */
+
+    buf = alloc(len+1);                /* trailing null */
+
+    /* Copy it across */
+
+    po = buf;
+
+    for (pi = str; *pi; pi++) {
+       switch (*pi) {
+       META_CHARS:
+#undef META_CHARS
+           *po++ = '\\';
+           /* fall through */
+       default:
+           *po++ = *pi;
+           break;
+       }
+    }
+
+    *po = '\0';
+
+    assert(po - buf == len);   /* Just checking! */
+
+    return buf;
+}
+#endif /* HAVE_SHQUOTE */
+
+/* Table lookup.
+*/
+int table_lookup(table, str)
+table_t *table;
+char *str;
+{
+       while(table->word != (char *)0) {
+               if (*table->word == *str &&
+                   strcmp(table->word, str) == 0) return table->value;
+               table++;
+       }
+
+       return table->value;
+}
+
+/* Reverse table lookup.
+*/
+char *table_lookup_r(table, val)
+table_t *table;
+int val;
+{
+       while(table->word != (char *)0) {
+               if (table->value == val) return table->word;
+               table++;
+       }
+
+       return (char *)0;
+}
+
+#ifdef TEST
+
+int main()
+{
+       char *str = NULL;
+       char *t[20];
+       int r;
+       char *sr;
+       int i;
+       int fd;
+
+       for(fd = 3; fd < 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
+                * descriptor, which in turn might be used as an index into
+                * an array (e.g. an fd_set).
+                */
+               close(fd);
+       }
+
+       set_pname("token test");
+
+       erroutput_type = ERR_INTERACTIVE;
+
+       printf("Testing split() with \" \" token separator\n");
+       while(1) {
+               printf("Input string: ");
+               amfree(str);
+               if ((str = agets(stdin)) == NULL) {
+                       printf("\n");
+                       break;
+               }
+               r = split(str, t, 20, " ");
+               printf("%d token%s:\n", r, (r == 1) ? "" : "s");
+               for (i=0; i <= r; i++) printf("tok[%d] = \"%s\"\n", i, t[i]);
+       }
+       amfree(str);
+       printf("\n");
+
+       printf("Testing quote()\n");
+       while(1) {
+               printf("Input string: ");
+               amfree(str);
+               if ((str = agets(stdin)) == NULL) {
+                       printf("\n");
+                       break;
+               }
+               sr = squote(str);
+               printf("Quoted   = \"%s\"\n", sr);
+               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]);
+               amfree(sr);
+       }
+       amfree(str);
+       return 0;
+}
+
+#endif
diff --git a/common-src/token.h b/common-src/token.h
new file mode 100644 (file)
index 0000000..5a3f925
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1997-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: token.h,v 1.10.8.3 2003/12/16 22:36:45 martinea Exp $
+ *
+ * interface to token module
+ */
+#ifndef TOKEN_H
+#define TOKEN_H
+
+#include "amanda.h"
+
+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, ...))
+    __attribute__ ((format (printf, 1, 2)));
+extern char *squote P((char *str));
+extern char *quotef P((char *sep, char *format, ...))
+    __attribute__ ((format (printf, 2, 3)));
+extern char *quote P((char *sep, char *str));
+extern char *rxquote P((char *str));
+#ifndef HAVE_SHQUOTE_DECL
+extern char *shquote P((char *str));
+#endif
+extern int table_lookup P((table_t *table, char *str));
+extern char *table_lookup_r P((table_t *table, int val));
+
+#endif
diff --git a/common-src/util.c b/common-src/util.c
new file mode 100644 (file)
index 0000000..cd3a465
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * 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: util.c,v 1.2.2.2.4.3.2.1 2002/03/31 21:01:33 jrjackson Exp $
+ */
+
+#include "amanda.h"
+#include "util.h"
+
+/*
+ * Keep calling read() until we've read buflen's worth of data, or EOF,
+ * or we get an error.
+ *
+ * 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;
+{
+    ssize_t nread, tot = 0;
+    char *buf = vbuf;  /* cast to char so we can ++ it */
+
+    while (buflen > 0) {
+       nread = read(fd, buf, buflen);
+       if (nread < 0)
+           return (nread);
+       if (nread == 0)
+           break;
+       tot += nread;
+       buf += nread;
+       buflen -= nread;
+    }
+    return (tot);
+}
+
+/*
+ * Keep calling write() until we've written buflen's worth of data,
+ * or we get an error.
+ *
+ * Returns the number of bytes written, or negative on error.
+ */
+ssize_t
+fullwrite(fd, vbuf, buflen)
+    int fd;
+    const void *vbuf;
+    size_t buflen;
+{
+    ssize_t nwritten, tot = 0;
+    const char *buf = vbuf;    /* cast to char so we can ++ it */
+
+    while (buflen > 0) {
+       nwritten = write(fd, buf, buflen);
+       if (nwritten < 0)
+           return (nwritten);
+       tot += nwritten;
+       buf += nwritten;
+       buflen -= nwritten;
+    }
+    return (tot);
+}
+
+/*
+ * Bind to a port in the given range.  Takes a begin,end pair of port numbers.
+ *
+ * Returns negative on error (EGAIN if all ports are in use).  Returns 0
+ * on success.
+ */
+int
+bind_portrange(s, addrp, first_port, last_port)
+    int s;
+    struct sockaddr_in *addrp;
+    int first_port, last_port;
+{
+    int port, cnt;
+    const int num_ports = last_port - first_port + 1;
+    int save_errno;
+
+    assert(first_port > 0 && first_port <= last_port && last_port < 65536);
+
+    /*
+     * 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;
+
+    /*
+     * Scan through the range, trying all available ports.  Wrap around
+     * if we don't happen to start at the beginning.
+     */
+    for (cnt = 0; cnt < num_ports; cnt++) {
+       addrp->sin_port = htons(port);
+       if (bind(s, (struct sockaddr *)addrp, sizeof(*addrp)) >= 0)
+           return 0;
+       /*
+        * If the error was something other then port in use, stop.
+        */
+       if (errno != EADDRINUSE)
+           break;
+       if (++port > last_port)
+           port = first_port;
+    }
+    if (cnt == num_ports) {
+       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;
+    }
+    return -1;
+}
+
+/*
+ * Construct a datestamp (YYYYMMDD) from a time_t.
+ */
+char *
+construct_datestamp(t)
+    time_t *t;
+{
+    struct tm *tm;
+    char datestamp[3*NUM_STR_SIZE];
+    time_t when;
+
+    if(t == NULL) {
+       when = time((time_t *)NULL);
+    } else {
+       when = *t;
+    }
+    tm = localtime(&when);
+    ap_snprintf(datestamp, sizeof(datestamp),
+                "%04d%02d%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
+    return stralloc(datestamp);
+}
+
+/*
+ * Construct a timestamp (YYYYMMDDHHMMSS) from a time_t.
+ */
+char *
+construct_timestamp(t)
+    time_t *t;
+{
+    struct tm *tm;
+    char timestamp[6*NUM_STR_SIZE];
+    time_t when;
+
+    if(t == NULL) {
+       when = time((time_t *)NULL);
+    } else {
+       when = *t;
+    }
+    tm = localtime(&when);
+    ap_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);
+}
diff --git a/common-src/util.h b/common-src/util.h
new file mode 100644 (file)
index 0000000..b692873
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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: util.h,v 1.2.2.1.4.2 2001/03/20 00:25:22 jrjackson Exp $
+ */
+#ifndef UTIL_H
+#define        UTIL_H
+
+ssize_t fullread P((int, void *, size_t));
+ssize_t fullwrite P((int, const void *, size_t));
+
+int bind_portrange P((int, struct sockaddr_in *, int, int));
+
+char *construct_datestamp P((time_t *t));
+char *construct_timestamp P((time_t *t));
+
+#endif /* UTIL_H */
diff --git a/common-src/version.c b/common-src/version.c
new file mode 100644 (file)
index 0000000..442d438
--- /dev/null
@@ -0,0 +1,32 @@
+/* version.c - generated by genversion.c - DO NOT EDIT! */
+char *version_info[] = {
+  "build: VERSION=\"Amanda-2.4.4p3\"\n",
+  "       BUILT_DATE=\"Tue Jun 22 08:43:12 EDT 2004\"\n",
+  "       BUILT_MACH=\"Linux minifee.iro.umontreal.ca 2.4.20-31.9 #1 Tue Apr 13 18:04:23 EDT 2004 i686 i686 i386 GNU/Linux\"\n",
+  "       CC=\"gcc\"\n",
+  "       CONFIGURE_COMMAND=\"'./configure' '--prefix=/u/martinea/linux' '--with-configdir=/u/martinea/etc/amanda' '--with-gnutar-listdir=/var/gnutar-lists' '--with-gnutar=/usr/local/amanda/bin/tar' '--with-bsd-security' '--with-user=amanda' '--with-group=amandag' '--disable-shared' '--mandir=/u/martinea/man'\"\n",
+  "paths: bindir=\"/u/martinea/linux/bin\"\n",
+  "       sbindir=\"/u/martinea/linux/sbin\"\n",
+  "       libexecdir=\"/u/martinea/linux/libexec\"\n",
+  "       mandir=\"/u/martinea/man\" AMANDA_TMPDIR=\"/tmp/amanda\"\n",
+  "       AMANDA_DBGDIR=\"/tmp/amanda\"\n",
+  "       CONFIG_DIR=\"/u/martinea/etc/amanda\" DEV_PREFIX=\"/dev/\"\n",
+  "       RDEV_PREFIX=\"/dev/\" DUMP=\"/sbin/dump\"\n",
+  "       RESTORE=\"/sbin/restore\" VDUMP=UNDEF VRESTORE=UNDEF\n",
+  "       XFSDUMP=UNDEF XFSRESTORE=UNDEF VXDUMP=UNDEF VXRESTORE=UNDEF\n",
+  "       SAMBA_CLIENT=\"/usr/bin/smbclient\"\n",
+  "       GNUTAR=\"/usr/local/amanda/bin/tar\"\n",
+  "       COMPRESS_PATH=\"/bin/gzip\" UNCOMPRESS_PATH=\"/bin/gzip\"\n",
+  "       LPRCMD=\"/usr/bin/lpr\" MAILER=\"/usr/bin/Mail\"\n",
+  "       listed_incr_dir=\"/var/gnutar-lists\"\n",
+  "defs:  DEFAULT_SERVER=\"minifee.iro.umontreal.ca\"\n",
+  "       DEFAULT_CONFIG=\"DailySet1\"\n",
+  "       DEFAULT_TAPE_SERVER=\"minifee.iro.umontreal.ca\"\n",
+  "       DEFAULT_TAPE_DEVICE=\"/dev/null\" HAVE_MMAP HAVE_SYSVSHM\n",
+  "       LOCKING=POSIX_FCNTL SETPGRP_VOID DEBUG_CODE\n",
+  "       AMANDA_DEBUG_DAYS=4 BSD_SECURITY USE_AMANDAHOSTS\n",
+  "       CLIENT_LOGIN=\"amanda\" FORCE_USERID HAVE_GZIP\n",
+  "       COMPRESS_SUFFIX=\".gz\" COMPRESS_FAST_OPT=\"--fast\"\n",
+  "       COMPRESS_BEST_OPT=\"--best\" UNCOMPRESS_OPT=\"-dc\"\n",
+  0
+};
diff --git a/common-src/version.h b/common-src/version.h
new file mode 100644 (file)
index 0000000..cae54ce
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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: version.h,v 1.4.4.1 1999/05/25 06:59:58 oliva Exp $
+ *
+ * interface to obtain the current amanda version
+ */
+/*
+ *     The printed version string is <major>.<minor>[.<patch>[comment]]
+ *      - Changes in comments imply a non-standard version of Amanda.
+ *     - Changes in patchlevel imply mostly bugfixes.
+ *     - Changes in minor version number imply significant code or protocol
+ *       changes or enhancements.
+ *     - Changes in major version number imply major reworking or redesign.
+ */
+
+#ifndef VERSION_H
+#define VERSION_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+extern const int   VERSION_MAJOR;
+extern const int   VERSION_MINOR;
+extern const int   VERSION_PATCH;
+extern const char * const VERSION_COMMENT;
+
+/* versionsuffix returns an empty string or a string like -2.3.0.4b1.  */
+extern char *versionsuffix();
+
+/* version returns a string representing the version of Amanda.  */
+extern char *version();
+
+#endif
diff --git a/common-src/versuff.c b/common-src/versuff.c
new file mode 100644 (file)
index 0000000..ff22961
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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: versuff.c.in,v 1.6.4.1.4.1 2001/07/20 19:37:20 jrjackson Exp $
+ *
+ * provide amanda version number and suffix appended to program names
+ */
+#include "amanda.h"
+#include "version.h"
+
+const int   VERSION_MAJOR   = 2;
+const int   VERSION_MINOR   = 4;
+const int   VERSION_PATCH   = 4;
+const char *const VERSION_COMMENT = "p3";
+
+char *
+versionsuffix()
+{
+#ifdef USE_VERSION_SUFFIXES
+       static char *vsuff = NULL;
+
+       if(vsuff) return vsuff;                 /* been here once already */
+
+       vsuff = stralloc2("-", version());
+       malloc_mark(vsuff);
+       return vsuff;
+#else
+       return "";
+#endif
+}
+
+char *
+version()
+{
+       static char *vsuff = NULL;
+       char major_str[NUM_STR_SIZE];
+       char minor_str[NUM_STR_SIZE];
+       char patch_str[NUM_STR_SIZE];
+
+       if(vsuff) return vsuff;                 /* been here once already */
+
+       ap_snprintf(major_str, sizeof(major_str), "%d", VERSION_MAJOR);
+       ap_snprintf(minor_str, sizeof(minor_str), "%d", VERSION_MINOR);
+       ap_snprintf(patch_str, sizeof(patch_str), "%d", VERSION_PATCH);
+
+       vsuff = vstralloc(major_str, ".", minor_str, ".", patch_str,
+                         VERSION_COMMENT,
+                         NULL);
+       malloc_mark(vsuff);
+       return vsuff;
+}
diff --git a/common-src/versuff.c.in b/common-src/versuff.c.in
new file mode 100644 (file)
index 0000000..9b32c83
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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: versuff.c.in,v 1.6.4.1.4.1 2001/07/20 19:37:20 jrjackson Exp $
+ *
+ * provide amanda version number and suffix appended to program names
+ */
+#include "amanda.h"
+#include "version.h"
+
+const int   VERSION_MAJOR   = @VERSION_MAJOR@;
+const int   VERSION_MINOR   = @VERSION_MINOR@;
+const int   VERSION_PATCH   = @VERSION_PATCH@;
+const char *const VERSION_COMMENT = @VERSION_COMMENT@;
+
+char *
+versionsuffix()
+{
+#ifdef USE_VERSION_SUFFIXES
+       static char *vsuff = NULL;
+
+       if(vsuff) return vsuff;                 /* been here once already */
+
+       vsuff = stralloc2("-", version());
+       malloc_mark(vsuff);
+       return vsuff;
+#else
+       return "";
+#endif
+}
+
+char *
+version()
+{
+       static char *vsuff = NULL;
+       char major_str[NUM_STR_SIZE];
+       char minor_str[NUM_STR_SIZE];
+       char patch_str[NUM_STR_SIZE];
+
+       if(vsuff) return vsuff;                 /* been here once already */
+
+       ap_snprintf(major_str, sizeof(major_str), "%d", VERSION_MAJOR);
+       ap_snprintf(minor_str, sizeof(minor_str), "%d", VERSION_MINOR);
+       ap_snprintf(patch_str, sizeof(patch_str), "%d", VERSION_PATCH);
+
+       vsuff = vstralloc(major_str, ".", minor_str, ".", patch_str,
+                         VERSION_COMMENT,
+                         NULL);
+       malloc_mark(vsuff);
+       return vsuff;
+}
diff --git a/common-src/waitpid.c b/common-src/waitpid.c
new file mode 100644 (file)
index 0000000..ee694d4
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+Copyright (c) 1990, 1991, 1992  X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+ *
+ * Copyright 1990, 1991, 1992 by UniSoft Group Limited.
+ * 
+ * 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 UniSoft not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.  UniSoft
+ * makes no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * $XConsortium: waitpid.c,v 1.3 94/04/17 20:59:56 rws Exp $
+ */
+
+/* modified for Amanda team:
+ * replaced all occurrences of "int" for status variables with "amwait_t"
+ * compile only if wait4() is not available; if it is, waitpid() is
+ * #defined to use wait4 instead.  */
+#include "config.h"
+
+#ifdef HAVE_WAIT4
+/* some compilers do not't like empty C sources */
+static void foo() {};
+
+#else
+
+#if 1
+#include "amanda.h"
+#else
+/* these are all included in amanda.h */
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#endif
+
+#ifdef DEBUG
+#   include <stdio.h>
+#   define     DBP(fmt,arg)    (fprintf(stderr, "waitpid(%d): ", currpid), \
+                                fprintf(stderr, fmt, arg), fflush(stderr))
+#else
+#   define     DBP(fmt,arg)
+#endif
+
+#define MAXTAB 20
+
+static struct {
+       pid_t pid;
+       amwait_t /*int*/ status;
+} savtab[MAXTAB];
+static int     ntab = 0;
+static pid_t   currpid = 0;
+
+pid_t
+waitpid(pid, stat_loc, options)
+pid_t pid;
+amwait_t /*int*/ *stat_loc;
+int options;
+{
+       int rval, i;
+       amwait_t /*int*/ local_loc;
+
+       /* Clear the table for each new process */
+       if (getpid() != currpid)
+       {
+               ntab = 0;
+               currpid = getpid();
+               DBP("clearing table\n", 0);
+       }
+
+       DBP("waiting for pid %d\n", pid);
+
+       if (options & ~(WNOHANG|WUNTRACED))
+       {
+               errno = EINVAL;
+               return -1;
+       }
+
+       if (pid == -1)
+       {
+               /* see if any saved */
+               for (i=0; i<ntab; i++)
+                       if (savtab[i].pid != 0)
+                       {
+                               pid = savtab[i].pid;
+                               if (stat_loc)
+                                       *stat_loc = savtab[i].status;
+                               savtab[i].pid = 0;
+                               DBP("got %d from table\n", pid);
+                               return pid;
+                       }
+
+               DBP("return wait3(...)\n", 0);
+               return wait3(stat_loc, options, (int *)0);
+       }
+
+       if (pid <= 0)
+       {
+               /* can't do this functionality (without reading /dev/kmem!) */
+               errno = EINVAL;
+               return -1;
+       }
+
+       /* see if already saved */
+       for (i=0; i<ntab; i++)
+               if (savtab[i].pid == pid)
+               {
+                       if (stat_loc)
+                               *stat_loc = savtab[i].status;
+                       savtab[i].pid = 0;
+                       DBP("found %d in table\n", pid);
+                       return pid;
+               }
+
+       rval = wait3(&local_loc, options, (int *)0);
+       DBP("wait3() returned %d\n", rval);
+       while (rval != pid && rval != -1 && rval != 0)
+       {
+               /* save for later */
+               for (i=0; i<ntab; i++)
+                       if (savtab[i].pid == 0)
+                       {
+                               savtab[i].pid = rval;
+                               savtab[i].status = local_loc;
+                               DBP("saved %d in free slot\n", rval);
+                               break;
+                       }
+               if (i == ntab)
+               {
+                       if (ntab < MAXTAB)
+                       {
+                               savtab[ntab].pid = rval;
+                               savtab[ntab].status = local_loc;
+                               ++ntab;
+                               DBP("saved %d in new slot\n", rval);
+                       }
+                       else
+                               DBP("no free slot for %d\n", rval);
+               }
+               rval = wait3(&local_loc, options, (int *)0);
+               DBP("wait3() returned %d\n", rval);
+       }
+
+       if(stat_loc)
+               *stat_loc = local_loc;
+
+       return rval;
+}
+#endif
diff --git a/config/Makefile.am b/config/Makefile.am
new file mode 100644 (file)
index 0000000..e58f070
--- /dev/null
@@ -0,0 +1,10 @@
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST =   acinclude.m4i   \
+               config.guess    \
+               config.sub      \
+               install-sh      \
+               libtool.m4i     \
+               ltmain.sh       \
+               missing         \
+               mkinstalldirs
diff --git a/config/Makefile.in b/config/Makefile.in
new file mode 100644 (file)
index 0000000..0e63c90
--- /dev/null
@@ -0,0 +1,430 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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@
+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 = :
+host_triplet = @host@
+subdir = config
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+       $(srcdir)/config.h.in config.guess config.sub depcomp \
+       install-sh ltmain.sh missing mkinstalldirs
+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 = config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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@
+EXTRA_DIST = acinclude.m4i     \
+               config.guess    \
+               config.sub      \
+               install-sh      \
+               libtool.m4i     \
+               ltmain.sh       \
+               missing         \
+               mkinstalldirs
+
+all: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+$(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  config/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  config/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
+
+config.h: stamp-h1
+       @if test ! -f $@; then \
+         rm -f stamp-h1; \
+         $(MAKE) stamp-h1; \
+       else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+       @rm -f stamp-h1
+       cd $(top_builddir) && $(SHELL) ./config.status config/config.h
+$(srcdir)/config.h.in:  $(am__configure_deps) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       rm -f stamp-h1
+       touch $@
+
+distclean-hdr:
+       -rm -f config.h stamp-h1
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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 config.h
+installdirs:
+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:
+       -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-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+       distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-hdr distclean-libtool \
+       distdir dvi dvi-am html html-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       uninstall uninstall-am uninstall-info-am
+
+# 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/config/acinclude.m4i b/config/acinclude.m4i
new file mode 100644 (file)
index 0000000..bcc2712
--- /dev/null
@@ -0,0 +1,1012 @@
+dnl Check if the compiler can handle unsigned long constants, ie 2ul.
+AC_DEFUN([AMANDA_C_UNSIGNED_LONG_CONSTANTS],
+    [
+       AC_CACHE_CHECK(
+           [for working unsigned long constants],
+           amanda_cv_c_unsigned_long_constants,
+           [
+               AC_TRY_COMPILE(
+                   [
+                   ],
+                   [
+                       long l = 1ul;
+                   ],
+                   amanda_cv_c_unsigned_long_constants=yes,
+                   amanda_cv_c_unsigned_long_constants=no
+               )
+           ]
+       )
+       if test "$amanda_cv_c_unsigned_long_constants" = yes; then
+           AC_DEFINE(HAVE_UNSIGNED_LONG_CONSTANTS,1,[Define if the compiler support unsigned long constants. ])
+       fi
+    ]
+)
+
+dnl Check for the argument type for shmat() and shmdt()
+AC_DEFUN([AMANDA_FUNC_SHM_ARG_TYPE],
+    [
+       AC_CACHE_CHECK(
+           [for shmdt() argument type],
+           amanda_cv_shmdt_arg_type,
+           [
+               if test "$ac_cv_func_shmget" = yes; then
+                   cat <<EOF >conftest.$ac_ext
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_IPC_H
+# include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+# include <sys/shm.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" void *shmat(int, void *, int);
+#else
+void *shmat();
+#endif
+
+int main()
+{
+    int i;
+    return 0;
+}
+EOF
+                   ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext >/dev/null 2>/dev/null
+                   if test $? = 0; then
+                       amanda_cv_shmdt_arg_type=void
+                   else
+                       amanda_cv_shmdt_arg_type=char
+                   fi
+                   rm -f conftest*
+               else
+                   amanda_cv_shmdt_arg_type=nothing
+               fi
+           ]
+       )
+       AC_DEFINE_UNQUOTED(SHM_ARG_TYPE,$amanda_cv_shmdt_arg_type,[Define to type of shmget() function argument. ])
+    ]
+)
+
+dnl Figure out the select() argument type.
+AC_DEFUN([AMANDA_FUNC_SELECT_ARG_TYPE],
+    [
+       AC_CACHE_CHECK(
+           [for select() argument type],
+           amanda_cv_select_arg_type,
+           [
+               rm -f conftest.c
+               cat <<EOF >conftest.$ac_ext
+#include "confdefs.h"
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#  include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int main()
+{
+#ifdef FD_SET_POINTER
+       (void)select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, 0);
+#else
+       (void)select(0, (int *) 0, (int *) 0, (int *) 0, 0);
+#endif
+       return 0;
+}
+EOF
+
+               dnl Figure out the select argument type by first trying to
+               dnl compile with the fd_set argument.  If the compile fails,
+               dnl then we know to use the int.  If it suceeds, then try to
+               dnl use the int.  If the int fails, then use fd_set.  If
+               dnl both suceeed, then do a line count on the number of
+               dnl lines that the compiler spit out, assuming that the
+               dnl compile outputing more lines had more errors.
+               amanda_cv_select_arg_type=no
+               select_compile="${CC-cc} -c $CFLAGS $CPPFLAGS"
+               $select_compile -DFD_SET_POINTER conftest.$ac_ext 1>conftest.fd_set 2>&1
+               if test $? -ne 0; then
+                   amanda_cv_select_arg_type=int
+               fi
+               if test "$amanda_cv_select_arg_type" = no; then
+                   $select_compile conftest.$ac_ext 1>conftest.int 2>&1
+                   if test $? -ne 0; then
+                       amanda_cv_select_arg_type=fd_set
+                   fi
+               fi
+               if test "$amanda_cv_select_arg_type" = no; then
+                   wc_fdset=`wc -l <conftest.fd_set`
+                   wc_int=`wc -l <conftest.int`
+                   if test "$wc_fdset" -le "$wc_int"; then
+                       amanda_cv_select_arg_type=fd_set
+                   else
+                       amanda_cv_select_arg_type=int
+                   fi
+               fi
+               rm -f conftest*
+           ]
+       )
+       AC_DEFINE_UNQUOTED(SELECT_ARG_TYPE,$amanda_cv_select_arg_type,[Define to type of select arguments. ])
+    ]
+)
+
+dnl Check if setsockopt can use the SO_SNDTIMEO option.
+dnl This defines HAVE_SO_SNDTIMEO if setsockopt works
+dnl with SO_SNDTIMEO.
+AC_DEFUN([AMANDA_FUNC_SETSOCKOPT_SO_SNDTIMEO],
+    [
+       AC_CACHE_CHECK(
+           [for setsockopt SO_SNDTIMEO option],
+           amanda_cv_setsockopt_SO_SNDTIMEO,
+           [
+               AC_TRY_RUN(
+                   [
+#include <sys/types.h>
+#include <sys/socket.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
+
+main() {
+#ifdef SO_SNDTIMEO
+    int sock = socket(AF_INET, SOCK_STREAM, 0);
+    struct timeval timeout;
+    timeout.tv_sec = 1;
+    timeout.tv_usec = 0;
+    return (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,
+             (void *)&timeout, sizeof(timeout)));
+#else
+    return -1;
+#endif
+}
+                   ],
+                   amanda_cv_setsockopt_SO_SNDTIMEO=yes,
+                   amanda_cv_setsockopt_SO_SNDTIMEO=no,
+                   amanda_cv_setsockopt_SO_SNDTIMEO=no
+               )
+           ]
+       )
+       if test "$amanda_cv_setsockopt_SO_SNDTIMEO" = yes; then
+           AC_DEFINE(HAVE_SO_SNDTIMEO,1,[Define if SO_SNDTIMEO is available. ])
+       fi
+    ]
+)
+
+dnl Find out how {awk,gawk,nawk,mawk} likes to assign variables, if it
+dnl can do so at all.
+AC_DEFUN([AMANDA_PROG_AWK_VAR],
+    [
+       AC_REQUIRE([AC_PROG_AWK])
+       AC_CACHE_CHECK(
+           [for $AWK command line variable assignment],
+           amanda_cv_awk_var_assignment,
+           [
+               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
+           ]
+       )
+       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
+       AC_SUBST(AWK_VAR_ASSIGNMENT_OPT)
+    ]
+)      
+
+dnl Check for the one or two argument version of gettimeofday.
+AC_DEFUN([AMANDA_FUNC_GETTIMEOFDAY_ARGS],
+    [
+       AC_REQUIRE([AC_HEADER_TIME])
+       AC_CACHE_CHECK(
+           [for gettimeofday number of arguments],
+           amanda_cv_gettimeofday_args,
+           [
+               AC_TRY_COMPILE(
+                   [
+#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
+                   ],
+                   [
+                       struct timeval val;
+                       struct timezone zone;
+                       gettimeofday(&val, &zone);
+                   ],
+                   amanda_cv_gettimeofday_args=2,
+                   amanda_cv_gettimeofday_args=1
+               )
+           ]
+       )
+       if test "$amanda_cv_gettimeofday_args" = 2; then
+           AC_DEFINE(HAVE_TWO_ARG_GETTIMEOFDAY,1,[Define if gettimeofday takes two arguments. ])
+       fi
+    ]
+)
+
+
+
+dnl Check if the compiler understands volatile.
+AC_DEFUN([AMANDA_C_VOLATILE],
+    [
+       AC_CACHE_CHECK(
+           [for working volatile],
+           amanda_cv_c_volatile,
+           [
+               AC_TRY_COMPILE(,
+                   [
+                       volatile int aaa = 0;
+                   ],
+                   amanda_cv_c_volatile=yes,
+                   amanda_cv_c_volatile=no
+               )
+           ]
+       )
+       if test $amanda_cv_c_volatile = no; then
+           AC_DEFINE(volatile, [],[Define to empty if the compiler does not support volatile. ])
+       fi
+    ]
+)
+
+
+dnl Check for if pid_t is a long, int, or short.
+AC_DEFUN([AMANDA_TYPE_PID_T],
+    [
+       AC_REQUIRE([AC_TYPE_PID_T])
+       AC_CACHE_CHECK([for pid_t type], amanda_cv_pid_type,
+           [
+               amanda_cv_pid_type=unknown
+               if test "$ac_cv_type_pid_t" = no; then
+                   amanda_cv_pid_type=int
+               fi
+               for TEST_amanda_cv_pid_type in long short int; do
+                   if test $amanda_cv_pid_type = unknown; then
+                       AC_EGREP_CPP(typedef.*${TEST_amanda_cv_pid_type}.*pid_t,
+                           [
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+                           ],
+                       amanda_cv_pid_type=$TEST_amanda_cv_pid_type)
+                   fi
+                   if test $amanda_cv_pid_type = unknown; then
+                       AC_EGREP_CPP(ZZZZ.*${TEST_amanda_cv_pid_type},
+                           [
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+                               ZZZZ pid_t
+                       ],
+                       amanda_cv_pid_type=$TEST_amanda_cv_pid_type)
+                   fi
+               done
+               if test $amanda_cv_pid_type = unknown; then
+                   amanda_cv_pid_type=int
+               fi
+           ]
+       )
+       case $amanda_cv_pid_type in
+           int)        AC_DEFINE_UNQUOTED(PRINTF_PID_T,"%d",[Define to printf formatting string to print a PID. ]) ;;
+           long)       AC_DEFINE_UNQUOTED(PRINTF_PID_T,"%ld") ;;
+           short)      AC_DEFINE_UNQUOTED(PRINTF_PID_T,"%d") ;;
+       esac
+    ]
+)
+
+dnl
+dnl
+dnl ICE_CHECK_DECL (FUNCTION, HEADER-FILE...)
+dnl If FUNCTION is available, define `HAVE_FUNCTION'.  If it is declared
+dnl in one of the headers named in the whitespace-separated list 
+dnl HEADER_FILE, define `HAVE_FUNCTION_DECL` (in all capitals).
+dnl
+AC_DEFUN([ICE_CHECK_DECL],
+[
+ice_have_$1=no
+AC_CHECK_FUNCS($1, ice_have_$1=yes)
+if test "${ice_have_$1}" = yes; then
+AC_MSG_CHECKING(for $1 declaration in $2)
+AC_CACHE_VAL(ice_cv_have_$1_decl,
+[
+ice_cv_have_$1_decl=no
+changequote(,)dnl
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+changequote([,])dnl
+for header in $2; do
+# Check for ordinary declaration
+AC_EGREP_HEADER([${ice_re_word}$1[     ]*\(], $header, 
+       ice_cv_have_$1_decl=yes)
+if test "$ice_cv_have_$1_decl" = yes; then
+       break
+fi
+# Check for "fixed" declaration like "getpid _PARAMS((int))"
+AC_EGREP_HEADER([${ice_re_word}$1[     ]*$ice_re_params\(\(], $header, 
+       ice_cv_have_$1_decl=yes)
+if test "$ice_cv_have_$1_decl" = yes; then
+       break
+fi
+done
+])
+AC_MSG_RESULT($ice_cv_have_$1_decl)
+if test "$ice_cv_have_$1_decl" = yes; then
+AC_DEFINE_UNQUOTED([HAVE_]translit($1,[a-z],[A-Z])[_DECL],1,[Define if $1 is declared. ])
+fi
+fi
+])dnl
+dnl Test for the presence of <sys/wait.h>, 'union wait', arg-type of 'wait()'.
+dnl by T.E.Dickey" , Jim Spath <jspath@mail.bcpl.lib.md.us>
+dnl
+dnl     FIXME: These tests should have been in autoconf 1.11!
+dnl
+dnl     Note that we cannot simply grep for 'union wait' in the wait.h file,
+dnl     because some Posix systems turn this on only when a BSD variable is
+dnl     defined. Since I'm trying to do without special defines, I'll live
+dnl     with the default behavior of the include-file.
+dnl
+dnl     I do _2_ compile checks, because we may have union-wait, but the
+dnl     prototype for 'wait()' may want an int.
+dnl
+dnl     Don't use HAVE_UNION_WAIT, because the autoconf documentation implies
+dnl     that if we've got union-wait, we'll automatically use it.
+dnl
+dnl Garrett Wollman adds:
+dnl    The tests described above don't quite do the right thing,
+dnl    since some systems have hacks which allow `union wait' to
+dnl    still work even though `int' is preferred (and generates
+dnl    fewer warnings).  Since all of these systems use prototypes,
+dnl    we can use the prototype of wait(2) to disambiguate them.
+dnl
+dnl Alexandre Oliva adds:
+dnl     A single compile check is enough.  If we don't have union wait,
+dnl     it's obvious that the test will fail, and that we must use int.
+dnl     If we do, the prototype (on STDC systems) and WIFEXITED will tell
+dnl     whether we're supposed to be using union wait instead of int.
+dnl
+AC_DEFUN([CF_WAIT],
+[
+AC_REQUIRE([AC_TYPE_PID_T])
+AC_HAVE_HEADERS(sys/wait.h wait.h)
+AC_CACHE_CHECK([whether wait uses union wait], [cf_cv_arg_union_wait],
+        [AC_TRY_COMPILE([
+#include <sys/types.h>
+
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#else
+# if HAVE_WAIT_H
+#  include <wait.h>
+# endif
+#endif
+
+#ifdef __STDC__
+pid_t wait(union wait *);
+#endif
+], [
+  union wait x; int i;
+  wait(&x); i = WIFEXITED(x)
+], [cf_cv_arg_union_wait=yes], [cf_cv_arg_union_wait=no])])
+if test $cf_cv_arg_union_wait = yes; then
+       AC_DEFINE(WAIT_USES_UNION,1,[Defined if wait() puts the status in a union wait instead of int. ])
+fi
+])dnl
+
+
+dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])]
+dnl
+dnl the "ISO C9X: 7.18 Integer types <stdint.h>" section requires the
+dnl existence of an include file <stdint.h> that defines a set of 
+dnl typedefs, especially uint8_t,int32_t,uintptr_t.
+dnl Many older installations will not provide this file, but some will
+dnl have the very same definitions in <inttypes.h>. In other enviroments
+dnl we can use the inet-types in <sys/types.h> which would define the
+dnl typedefs int8_t and u_int8_t respectivly.
+dnl
+dnl This macros will create a local "_stdint.h" or the headerfile given as 
+dnl an argument. In many cases that file will just "#include <stdint.h>" 
+dnl or "#include <inttypes.h>", while in other environments it will provide 
+dnl the set of basic 'stdint's definitions/typedefs: 
+dnl   int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t
+dnl   int_least32_t.. int_fast32_t.. intmax_t
+dnl which may or may not rely on the definitions of other files,
+dnl or using the AC_CHECK_SIZEOF macro to determine the actual
+dnl sizeof each type.
+dnl
+dnl if your header files require the stdint-types you will want to create an
+dnl installable file mylib-int.h that all your other installable header
+dnl may include. So if you have a library package named "mylib", just use
+dnl      AX_CREATE_STDINT_H(mylib-int.h) 
+dnl in configure.ac and go to install that very header file in Makefile.am
+dnl along with the other headers (mylib.h) - and the mylib-specific headers
+dnl can simply use "#include <mylib-int.h>" to obtain the stdint-types.
+dnl
+dnl Remember, if the system already had a valid <stdint.h>, the generated
+dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things...
+dnl
+dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/)
+dnl @version $Id: acinclude.m4i,v 1.1.2.5.6.2 2004/04/29 20:47:40 martinea Exp $
+dnl @author  Guido Draheim <guidod@gmx.de> 
+
+AC_DEFUN([AX_CREATE_STDINT_H],
+[# ------ AX CREATE STDINT H -------------------------------------
+AC_MSG_CHECKING([for stdint types])
+ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)`
+# try to shortcircuit - if the default include path of the compiler
+# can find a "stdint.h" header then we assume that all compilers can.
+AC_CACHE_VAL([ac_cv_header_stdint_t],[
+old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
+old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
+old_CFLAGS="$CFLAGS"     ; CFLAGS=""
+AC_TRY_COMPILE([#include <stdint.h>],[int_least32_t v = 0;],
+[ac_cv_stdint_result="(assuming C99 compatible system)"
+ ac_cv_header_stdint_t="stdint.h"; ],
+[ac_cv_header_stdint_t=""])
+CXXFLAGS="$old_CXXFLAGS"
+CPPFLAGS="$old_CPPFLAGS"
+CFLAGS="$old_CFLAGS" ])
+
+v="... $ac_cv_header_stdint_h"
+if test "$ac_stdint_h" = "stdint.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)])
+elif test "$ac_stdint_h" = "inttypes.h" ; then
+ AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)])
+elif test "_$ac_cv_header_stdint_t" = "_" ; then
+ AC_MSG_RESULT([(putting them into $ac_stdint_h)$v])
+else
+ ac_cv_header_stdint="$ac_cv_header_stdint_t"
+ AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)])
+fi
+
+if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit..
+
+dnl .....intro message done, now do a few system checks.....
+dnl btw, all CHECK_TYPE macros do automatically "DEFINE" a type, therefore
+dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead
+
+inttype_headers=`echo $2 | sed -e 's/,/ /g'`
+
+ac_cv_stdint_result="(no helpful system typedefs seen)"
+AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[
+ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
+  AC_MSG_RESULT([(..)])
+  for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_uintptr_t 
+   unset ac_cv_type_uint64_t
+   _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen uintptr_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint uintptr_t])
+ ])
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[
+ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
+  AC_MSG_RESULT([(..)])
+  for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do
+   unset ac_cv_type_uint32_t
+   unset ac_cv_type_uint64_t
+   AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen uint32_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint uint32_t])
+ ])
+fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+if test "_$ac_cv_header_stdint_o" = "_" ; then
+AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[
+ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
+  AC_MSG_RESULT([(..)])
+  for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_u_int32_t
+   unset ac_cv_type_u_int64_t
+   AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl
+     continue,[#include <$i>])
+   AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>])
+   ac_cv_stdint_result="(seen u_int32_t$and64 in $i)"
+   break;
+  done
+  AC_MSG_CHECKING([for stdint u_int32_t])
+ ])
+fi fi
+
+dnl if there was no good C99 header file, do some typedef checks...
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+   AC_MSG_CHECKING([for stdint datatype model])
+   AC_MSG_RESULT([(..)])
+   AC_CHECK_SIZEOF(char)
+   AC_CHECK_SIZEOF(short)
+   AC_CHECK_SIZEOF(int)
+   AC_CHECK_SIZEOF(long)
+   AC_CHECK_SIZEOF(void*)
+   ac_cv_stdint_char_model=""
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model=""
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp"
+   name="$ac_cv_stdint_long_model"
+   case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in
+    122/242)     name="$name,  IP16 (standard 16bit machine)" ;;
+    122/244)     name="$name,  LP32 (standard 32bit mac/win)" ;;
+    122/*)       name="$name        (unusual int16 model)" ;; 
+    124/444)     name="$name, ILP32 (standard 32bit unixish)" ;;
+    124/488)     name="$name,  LP64 (standard 64bit unixish)" ;;
+    124/448)     name="$name, LLP64 (unusual  64bit unixish)" ;;
+    124/*)       name="$name        (unusual int32 model)" ;; 
+    128/888)     name="$name, ILP64 (unusual  64bit numeric)" ;;
+    128/*)       name="$name        (unusual int64 model)" ;; 
+    222/*|444/*) name="$name        (unusual dsptype)" ;;
+     *)          name="$name        (very unusal model)" ;;
+   esac
+   AC_MSG_RESULT([combined for stdint datatype model...  $name])
+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
+
+AC_MSG_CHECKING([for extra inttypes in chosen header])
+AC_MSG_RESULT([($ac_cv_header_stdint)])
+dnl see if int_least and int_fast types are present in _this_ header.
+unset ac_cv_type_int_least32_t
+unset ac_cv_type_int_fast32_t
+AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>])
+AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>])
+AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>])
+
+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
+
+AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl
+$ac_cv_stdint_result])
+
+# ----------------- DONE inttypes.h checks START header -------------
+AC_CONFIG_COMMANDS([$ac_stdint_h],[
+AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h)
+ac_stdint=$tmp/_stdint.h
+
+echo "#ifndef" $_ac_stdint_h >$ac_stdint
+echo "#define" $_ac_stdint_h "1" >>$ac_stdint
+echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
+echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
+echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_t" != "_" ; then 
+echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
+fi
+
+cat >>$ac_stdint <<STDINT_EOF
+
+/* ................... shortcircuit part ........................... */
+
+#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <stddef.h>
+
+/* .................... configured part ............................ */
+
+STDINT_EOF
+
+echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+  ac_header="$ac_cv_header_stdint_x"
+  echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
+fi
+
+echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_o" != "_" ; then
+  ac_header="$ac_cv_header_stdint_o"
+  echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
+fi
+
+echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_u" != "_" ; then
+  ac_header="$ac_cv_header_stdint_u"
+  echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
+fi
+
+echo "" >>$ac_stdint
+
+if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
+  echo "#include <$ac_header>" >>$ac_stdint
+  echo "" >>$ac_stdint
+fi fi
+
+echo "/* which 64bit typedef has been found */" >>$ac_stdint
+if test "$ac_cv_type_uint64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_UINT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
+fi
+if test "$ac_cv_type_u_int64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_U_INT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* which type model has been detected */" >>$ac_stdint
+if test "_$ac_cv_stdint_char_model" != "_" ; then
+echo "#define   _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint
+echo "#define   _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint
+else
+echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
+echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* whether int_least types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_least32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_LEAST32_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
+fi
+echo "/* whether int_fast types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_fast32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
+fi
+echo "/* whether intmax_t type was detected */" >>$ac_stdint
+if test "$ac_cv_type_intmax_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+  cat >>$ac_stdint <<STDINT_EOF
+/* .................... detections part ............................ */
+
+/* whether we need to define bitspecific types from compiler base types */
+#ifndef _STDINT_HEADER_INTPTR
+#ifndef _STDINT_HEADER_UINT32
+#ifndef _STDINT_HEADER_U_INT32
+#define _STDINT_NEED_INT_MODEL_T
+#else
+#define _STDINT_HAVE_U_INT_TYPES
+#endif
+#endif
+#endif
+
+#ifdef _STDINT_HAVE_U_INT_TYPES
+#undef _STDINT_NEED_INT_MODEL_T
+#endif
+
+#ifdef  _STDINT_CHAR_MODEL
+#if     _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
+#ifndef _STDINT_BYTE_MODEL
+#define _STDINT_BYTE_MODEL 12
+#endif
+#endif
+#endif
+
+#ifndef _STDINT_HAVE_INT_LEAST32_T
+#define _STDINT_NEED_INT_LEAST_T
+#endif
+
+#ifndef _STDINT_HAVE_INT_FAST32_T
+#define _STDINT_NEED_INT_FAST_T
+#endif
+
+#ifndef _STDINT_HEADER_INTPTR
+#define _STDINT_NEED_INTPTR_T
+#ifndef _STDINT_HAVE_INTMAX_T
+#define _STDINT_NEED_INTMAX_T
+#endif
+#endif
+
+
+/* .................... definition part ............................ */
+
+/* some system headers have good uint64_t */
+#ifndef _HAVE_UINT64_T
+#if     defined _STDINT_HAVE_UINT64_T  || defined HAVE_UINT64_T
+#define _HAVE_UINT64_T
+#elif   defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
+#define _HAVE_UINT64_T
+typedef u_int64_t uint64_t;
+#endif
+#endif
+
+#ifndef _HAVE_UINT64_T
+/* .. here are some common heuristics using compiler runtime specifics */
+#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+#elif !defined __STRICT_ANSI__
+#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+#define _HAVE_UINT64_T
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
+/* note: all ELF-systems seem to have loff-support which needs 64-bit */
+#if !defined _NO_LONGLONG
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#elif defined __alpha || (defined __mips && defined _ABIN32)
+#if !defined _NO_LONGLONG
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#endif
+  /* compiler/cpu type to define int64_t */
+#endif
+#endif
+#endif
+
+#if defined _STDINT_HAVE_U_INT_TYPES
+/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+
+/* glibc compatibility */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INT_MODEL_T
+/* we must guess all the basic types. Apart from byte-adressable system, */
+/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
+/* (btw, those nibble-addressable systems are way off, or so we assume) */
+
+dnl   /* have a look at "64bit and data size neutrality" at */
+dnl   /* http://unix.org/version2/whatsnew/login_64bit.html */
+dnl   /* (the shorthand "ILP" types always have a "P" part) */
+
+#if defined _STDINT_BYTE_MODEL
+#if _STDINT_LONG_MODEL+0 == 242
+/* 2:4:2 =  IP16 = a normal 16-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned long   uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          long    int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
+/* 2:4:4 =  LP32 = a 32-bit system derived from a 16-bit */
+/* 4:4:4 = ILP32 = a normal 32-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
+/* 4:8:4 =  IP32 = a 32-bit system prepared for 64-bit    */
+/* 4:8:8 =  LP64 = a normal 64-bit system                 */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* this system has a "long" of 64bit */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long   uint64_t;
+typedef          long    int64_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 448
+/*      LLP64   a 64-bit system derived from a 32-bit system */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* assuming the system has a "long long" */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long long uint64_t;
+typedef          long long  int64_t;
+#endif
+#else
+#define _STDINT_NO_INT32_T
+#endif
+#else
+#define _STDINT_NO_INT8_T
+#define _STDINT_NO_INT32_T
+#endif
+#endif
+
+/*
+ * quote from SunOS-5.8 sys/inttypes.h:
+ * Use at your own risk.  As of February 1996, the committee is squarely
+ * behind the fixed sized types; the "least" and "fast" types are still being
+ * discussed.  The probability that the "fast" types may be removed before
+ * the standard is finalized is high enough that they are not currently
+ * implemented.
+ */
+
+#if defined _STDINT_NEED_INT_LEAST_T
+typedef  int8_t    int_least8_t;
+typedef  int16_t   int_least16_t;
+typedef  int32_t   int_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_least64_t;
+#endif
+
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_least64_t;
+#endif
+  /* least types */
+#endif
+
+#if defined _STDINT_NEED_INT_FAST_T
+typedef  int8_t    int_fast8_t; 
+typedef  int       int_fast16_t;
+typedef  int32_t   int_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_fast64_t;
+#endif
+
+typedef uint8_t   uint_fast8_t; 
+typedef unsigned  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_fast64_t;
+#endif
+  /* fast types */
+#endif
+
+#ifdef _STDINT_NEED_INTMAX_T
+#ifdef _HAVE_UINT64_T
+typedef  int64_t       intmax_t;
+typedef uint64_t      uintmax_t;
+#else
+typedef          long  intmax_t;
+typedef unsigned long uintmax_t;
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INTPTR_T
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+/* we encourage using "long" to store pointer values, never use "int" ! */
+#if   _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
+typedef  unsinged int   uintptr_t;
+typedef           int    intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
+typedef        uint64_t uintptr_t;
+typedef         int64_t  intptr_t;
+#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#endif
+#endif
+#endif
+
+  /* shortcircuit*/
+#endif
+  /* once */
+#endif
+#endif
+STDINT_EOF
+    if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
+      AC_MSG_NOTICE([$ac_stdint_h is unchanged])
+    else
+      ac_dir=`AS_DIRNAME(["$ac_stdint_h"])`
+      AS_MKDIR_P(["$ac_dir"])
+      rm -f $ac_stdint_h
+      mv $ac_stdint $ac_stdint_h
+    fi
+],[# variables for create stdint.h replacement
+PACKAGE="$PACKAGE"
+VERSION="$VERSION"
+ac_stdint_h="$ac_stdint_h"
+_ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h)
+ac_cv_stdint_message="$ac_cv_stdint_message"
+ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
+ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
+ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
+ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_stdint_char_model="$ac_cv_stdint_char_model"
+ac_cv_stdint_long_model="$ac_cv_stdint_long_model"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
+])
+])
diff --git a/config/config.guess b/config/config.guess
new file mode 100755 (executable)
index 0000000..51fab47
--- /dev/null
@@ -0,0 +1,1459 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2004-03-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+       for c in cc gcc c89 c99 ; do
+         if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # NetBSD (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       #
+       # Note: NetBSD doesn't particularly care about the vendor
+       # portion of the name.  We always set it to "unknown".
+       sysctl="sysctl -n hw.machine_arch"
+       UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+           /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+       case "${UNAME_MACHINE_ARCH}" in
+           armeb) machine=armeb-unknown ;;
+           arm*) machine=arm-unknown ;;
+           sh3el) machine=shl-unknown ;;
+           sh3eb) machine=sh-unknown ;;
+           *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE_ARCH}" in
+           arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       # Debian GNU/NetBSD machines have a different userland, and
+       # thus, need a distinct triplet. However, they do not need
+       # kernel version information, so it can be replaced with a
+       # suitable tag, in the style of linux-gnu.
+       case "${UNAME_VERSION}" in
+           Debian*)
+               release='-gnu'
+               ;;
+           *)
+               release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+               ;;
+       esac
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    amd64:OpenBSD:*:*)
+       echo x86_64-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    cats:OpenBSD:*:*)
+       echo arm-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pegasos:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:ekkoBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:MirBSD:*:*)
+       echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:MirBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       case $UNAME_RELEASE in
+       *4.0)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+               ;;
+       *5.*)
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+               ;;
+       esac
+       # According to Compaq, /usr/sbin/psrinfo has been available on
+       # OSF/1 and Tru64 systems produced since 1995.  I hope that
+       # covers most systems running today.  This code pipes the CPU
+       # types through head -n 1, so we only detect the type of CPU 0.
+       ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+       case "$ALPHA_CPU_TYPE" in
+           "EV4 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "EV4.5 (21064)")
+               UNAME_MACHINE="alpha" ;;
+           "LCA4 (21066/21068)")
+               UNAME_MACHINE="alpha" ;;
+           "EV5 (21164)")
+               UNAME_MACHINE="alphaev5" ;;
+           "EV5.6 (21164A)")
+               UNAME_MACHINE="alphaev56" ;;
+           "EV5.6 (21164PC)")
+               UNAME_MACHINE="alphapca56" ;;
+           "EV5.7 (21164PC)")
+               UNAME_MACHINE="alphapca57" ;;
+           "EV6 (21264)")
+               UNAME_MACHINE="alphaev6" ;;
+           "EV6.7 (21264A)")
+               UNAME_MACHINE="alphaev67" ;;
+           "EV6.8CB (21264C)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8AL (21264B)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.8CX (21264D)")
+               UNAME_MACHINE="alphaev68" ;;
+           "EV6.9A (21264/EV69A)")
+               UNAME_MACHINE="alphaev69" ;;
+           "EV7 (21364)")
+               UNAME_MACHINE="alphaev7" ;;
+           "EV7.9 (21364A)")
+               UNAME_MACHINE="alphaev79" ;;
+       esac
+       # A Pn.n version is a patched version.
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+       echo alpha-hp-vms
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+       echo sparc-icl-nx6
+       exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+       case `/usr/bin/uname -p` in
+           sparc) echo sparc-icl-nx7 && exit 0 ;;
+       esac ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    m68k:machten:*:*)
+       echo m68k-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c \
+         && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && exit 0
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               eval $set_cc_for_build
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+               if [ -x /usr/bin/getconf ]; then
+                   sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                         '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+               fi
+               if [ "${HP_ARCH}" = "" ]; then
+                   eval $set_cc_for_build
+                   sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+                   (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+                   test -z "$HP_ARCH" && HP_ARCH=hppa
+               fi ;;
+       esac
+       if [ ${HP_ARCH} = "hppa2.0w" ]
+       then
+           # avoid double evaluation of $set_cc_for_build
+           test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+           then
+               HP_ARCH="hppa2.0w"
+           else
+               HP_ARCH="hppa64"
+           fi
+       fi
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    *:UNICOS/mp:*:*)
+       echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+       exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       # Determine whether the default compiler uses glibc.
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #if __GLIBC__ >= 2
+       LIBC=gnu
+       #else
+       LIBC=
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       # GNU/KFreeBSD systems have a "k" prefix to indicate we are using
+       # FreeBSD's kernel, but not the complete OS.
+       case ${LIBC} in gnu) kernel_only='k' ;; esac
+       echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    x86:Interix*:[34]*)
+       echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+       exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+       echo i${UNAME_MACHINE}-pc-mks
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i586-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       # the GNU system
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *:GNU/*:*:*)
+       # other systems with GNU libc and userland
+       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    cris:Linux:*:*)
+       echo cris-axis-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    m32r*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips
+       #undef mipsel
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mipsel
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+       ;;
+    mips64:Linux:*:*)
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #undef CPU
+       #undef mips64
+       #undef mips64el
+       #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+       CPU=mips64el
+       #else
+       #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+       CPU=mips64
+       #else
+       CPU=
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+       test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh64*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       # Set LC_ALL=C to ensure ld outputs messages in English.
+       ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #ifdef __ELF__
+       # ifdef __GLIBC__
+       #  if __GLIBC__ >= 2
+       LIBC=gnu
+       #  else
+       LIBC=gnulibc1
+       #  endif
+       # else
+       LIBC=gnulibc1
+       # endif
+       #else
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+       #ifdef __dietlibc__
+       LIBC=dietlibc
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit 0 ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit 0 ;;
+       i*86:syllable:*:*)
+       echo ${UNAME_MACHINE}-pc-syllable
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+       echo m68k-convergent-sysv
+       exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+       echo m68k-diab-dnix
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+       echo sx6-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       case `uname -p` in
+           *86) UNAME_PROCESSOR=i686 ;;
+           powerpc) UNAME_PROCESSOR=powerpc ;;
+       esac
+       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       UNAME_PROCESSOR=`uname -p`
+       if test "$UNAME_PROCESSOR" = "x86"; then
+               UNAME_PROCESSOR=i386
+               UNAME_MACHINE=pc
+       fi
+       echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+       exit 0 ;;
+    *:DragonFly:*:*)
+       echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config/config.h.in b/config/config.h.in
new file mode 100644 (file)
index 0000000..b8a365c
--- /dev/null
@@ -0,0 +1,1267 @@
+/* config/config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define on AIX. */
+#undef AIX_BACKUP
+
+/* Define on AIX. */
+#undef AIX_TAPEIO
+
+/* Location of Amanda directories and files. */
+#undef AMANDA_DBGDIR
+
+/* Number of days to keep debugging files. */
+#undef AMANDA_DEBUG_DAYS
+
+/* The name for the Amanda service. */
+#undef AMANDA_SERVICE_NAME
+
+/* The directory in which Amanda should create temporary files. */
+#undef AMANDA_TMPDIR
+
+/* Define if you want assertion checking. */
+#undef ASSERTIONS
+
+/* Define as the user who owns installed binaries. */
+#undef BINARY_OWNER
+
+/* Define to use BSD .rhosts/.amandahosts security. */
+#undef BSD_SECURITY
+
+/* The Kerberos client host instance. */
+#undef CLIENT_HOST_INSTANCE
+
+/* The Kerberos client host key file. */
+#undef CLIENT_HOST_KEY_FILE
+
+/* The Kerberos client host principle. */
+#undef CLIENT_HOST_PRINCIPLE
+
+/* Define as a the user to force to on client machines. */
+#undef CLIENT_LOGIN
+
+/* Define to 1 if the `closedir' function returns void instead of `int'. */
+#undef CLOSEDIR_VOID
+
+/* Define as the command line option for best compression. */
+#undef COMPRESS_BEST_OPT
+
+/* Define as the command line option for fast compression. */
+#undef COMPRESS_FAST_OPT
+
+/* Define to the exact path to the gzip or the compress program. */
+#undef COMPRESS_PATH
+
+/* Define to the suffix for the COMPRESS_PATH compression program. */
+#undef COMPRESS_SUFFIX
+
+/* Saves the original ./configure command line arguments */
+#undef CONFIGURE_COMMAND
+
+/* The directory in which configuration directories should be created. */
+#undef CONFIG_DIR
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define if you want debugging. */
+#undef DEBUG_CODE
+
+/* This is the default changer device. */
+#undef DEFAULT_CHANGER_DEVICE
+
+/* This is the default Amanda configuration. */
+#undef DEFAULT_CONFIG
+
+/* For Linux systems with floppy tapes: * QIC volume table support via raw
+   tape device. */
+#undef DEFAULT_RAW_TAPE_DEVICE
+
+/* This is the default Amanda index server. */
+#undef DEFAULT_SERVER
+
+/* This is the default no-rewinding tape device. */
+#undef DEFAULT_TAPE_DEVICE
+
+/* This is the default restoring Amanda tape server. */
+#undef DEFAULT_TAPE_SERVER
+
+/* Define as the prefix for disk devices, commonly /dev/ or /dev/dsk/ */
+#undef DEV_PREFIX
+
+/* Define on Cygwin. */
+#undef DONT_SUID_ROOT
+
+/* Define the location of the ufsdump, backup, or dump program. */
+#undef DUMP
+
+/* Define if dumper should buffer the sockets for faster throughput. */
+#undef DUMPER_SOCKET_BUFFERING
+
+/* Define this if this system's dump exits with 1 as a success code. */
+#undef DUMP_RETURNS_1
+
+/* Define to force to another user on client machines. */
+#undef FORCE_USERID
+
+/* Define to 1 if the `getpgrp' function requires zero arguments. */
+#undef GETPGRP_VOID
+
+/* Define to the location of Gnu tar. */
+#undef GNUTAR
+
+/* The directory in which GNU tar should store directory lists for
+   incrementals. */
+#undef GNUTAR_LISTED_INCREMENTAL_DIR
+
+/* Define the location of the grep program. */
+#undef GREP
+
+/* Define to 1 if you have the `accept' function. */
+#undef HAVE_ACCEPT
+
+/* Define if accept is declared. */
+#undef HAVE_ACCEPT_DECL
+
+/* Define to enable AIX tape-changer support */
+#undef HAVE_AIX_LIKE_SCSI
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if you have the `atof' function. */
+#undef HAVE_ATOF
+
+/* Define if atof is declared. */
+#undef HAVE_ATOF_DECL
+
+/* Define to 1 if you have the `basename' function. */
+#undef HAVE_BASENAME
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Define if bcopy is declared. */
+#undef HAVE_BCOPY_DECL
+
+/* Define to 1 if you have the `bind' function. */
+#undef HAVE_BIND
+
+/* Define if bind is declared. */
+#undef HAVE_BIND_DECL
+
+/* Define this if issuing a fsf on a tape fails when you are not at a tape *
+   mark, for instance, if amrecover gives I/O errors when skipping. */
+#undef HAVE_BROKEN_FSF
+
+/* Define to enable BSD tape-changer support */
+#undef HAVE_BSD_LIKE_SCSI
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* Define if bzero is declared. */
+#undef HAVE_BZERO_DECL
+
+/* Define to 1 if you have the <camlib.h> header file. */
+#undef HAVE_CAMLIB_H
+
+/* Define to 1 if you have the <cam/cam.h> header file. */
+#undef HAVE_CAM_CAM_H
+
+/* Define to enable CAM tape-changer support */
+#undef HAVE_CAM_LIKE_SCSI
+
+/* Define to 1 if you have the <cam/scsi/scsi_message.h> header file. */
+#undef HAVE_CAM_SCSI_SCSI_MESSAGE_H
+
+/* Define if limits.h defines CHAR_BIT. */
+#undef HAVE_CHAR_BIT
+
+/* Define if limits.h defines CHAR_MAX. */
+#undef HAVE_CHAR_MAX
+
+/* Define if limits.h defines CHAR_MIN. */
+#undef HAVE_CHAR_MIN
+
+/* Define to 1 if you have the <chio.h> header file. */
+#undef HAVE_CHIO_H
+
+/* Define to 1 if you have the `closelog' function. */
+#undef HAVE_CLOSELOG
+
+/* Define if closelog is declared. */
+#undef HAVE_CLOSELOG_DECL
+
+/* Define to 1 if you have the `connect' function. */
+#undef HAVE_CONNECT
+
+/* Define if connect is declared. */
+#undef HAVE_CONNECT_DECL
+
+/* Define to 1 if you have the <dbm.h> header file. */
+#undef HAVE_DBM_H
+
+/* Define to 1 if you have the `dbm_open' function. */
+#undef HAVE_DBM_OPEN
+
+/* Define if dbm_open is declared. */
+#undef HAVE_DBM_OPEN_DECL
+
+/* Define to 1 if you have the <db.h> header file. */
+#undef HAVE_DB_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* Define to the string that enables dump estimates. */
+#undef HAVE_DUMP_ESTIMATE
+
+/* Define to 1 if you have the `endmntent' function. */
+#undef HAVE_ENDMNTENT
+
+/* Define to 1 if you have the `fclose' function. */
+#undef HAVE_FCLOSE
+
+/* Define if fclose is declared. */
+#undef HAVE_FCLOSE_DECL
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fflush' function. */
+#undef HAVE_FFLUSH
+
+/* Define if fflush is declared. */
+#undef HAVE_FFLUSH_DECL
+
+/* Define to 1 if you have the `flock' function. */
+#undef HAVE_FLOCK
+
+/* Define if flock is declared. */
+#undef HAVE_FLOCK_DECL
+
+/* Define to 1 if you have the `fnmatch' function. */
+#undef HAVE_FNMATCH
+
+/* Define to 1 if you have the <fnmatch.h> header file. */
+#undef HAVE_FNMATCH_H
+
+/* Define to 1 if you have the `fprintf' function. */
+#undef HAVE_FPRINTF
+
+/* Define if fprintf is declared. */
+#undef HAVE_FPRINTF_DECL
+
+/* Define to 1 if you have the `fputc' function. */
+#undef HAVE_FPUTC
+
+/* Define if fputc is declared. */
+#undef HAVE_FPUTC_DECL
+
+/* Define to 1 if you have the `fputs' function. */
+#undef HAVE_FPUTS
+
+/* Define if fputs is declared. */
+#undef HAVE_FPUTS_DECL
+
+/* Define to 1 if you have the `fread' function. */
+#undef HAVE_FREAD
+
+/* Define if fread is declared. */
+#undef HAVE_FREAD_DECL
+
+/* Define to 1 if you have the `fseek' function. */
+#undef HAVE_FSEEK
+
+/* Define if fseek is declared. */
+#undef HAVE_FSEEK_DECL
+
+/* Define to 1 if you have the <fstab.h> header file. */
+#undef HAVE_FSTAB_H
+
+/* Define to 1 if you have the `fwrite' function. */
+#undef HAVE_FWRITE
+
+/* Define if fwrite is declared. */
+#undef HAVE_FWRITE_DECL
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getfsent' function. */
+#undef HAVE_GETFSENT
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define if gethostname is declared. */
+#undef HAVE_GETHOSTNAME_DECL
+
+/* Define to 1 if you have the `getmntent' function. */
+#undef HAVE_GETMNTENT
+
+/* Define to 1 if you have the `getopt' function. */
+#undef HAVE_GETOPT
+
+/* Define if getopt is declared. */
+#undef HAVE_GETOPT_DECL
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getpeername' function. */
+#undef HAVE_GETPEERNAME
+
+/* Define if getpeername is declared. */
+#undef HAVE_GETPEERNAME_DECL
+
+/* Define to 1 if you have the `getpgrp' function. */
+#undef HAVE_GETPGRP
+
+/* Define to 1 if you have the `getsockname' function. */
+#undef HAVE_GETSOCKNAME
+
+/* Define if getsockname is declared. */
+#undef HAVE_GETSOCKNAME_DECL
+
+/* Define to 1 if you have the `getsockopt' function. */
+#undef HAVE_GETSOCKOPT
+
+/* Define if getsockopt is declared. */
+#undef HAVE_GETSOCKOPT_DECL
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if gettimeofday is declared. */
+#undef HAVE_GETTIMEOFDAY_DECL
+
+/* Define to 1 if you have the `getvfsent' function. */
+#undef HAVE_GETVFSENT
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if Amanda is using the gzip program. */
+#undef HAVE_GZIP
+
+/* Define to 1 if you have the <history.h> header file. */
+#undef HAVE_HISTORY_H
+
+/* Define this if dump accepts -h for honoring nodump. */
+#undef HAVE_HONOR_NODUMP
+
+/* Define to enable HPUX tape-changer support. */
+#undef HAVE_HPUX_LIKE_SCSI
+
+/* Define to enable HPUX chio based changer support. */
+#undef HAVE_HPUX_SCSI_CHIO
+
+/* Define to 1 if you have the `initgroups' function. */
+#undef HAVE_INITGROUPS
+
+/* Define if initgroups is declared. */
+#undef HAVE_INITGROUPS_DECL
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `ioctl' function. */
+#undef HAVE_IOCTL
+
+/* Define if ioctl is declared. */
+#undef HAVE_IOCTL_DECL
+
+/* Define to enable IRIX tape-changer support */
+#undef HAVE_IRIX_LIKE_SCSI
+
+/* Define to 1 if you have the `isascii' function. */
+#undef HAVE_ISASCII
+
+/* Define to 1 if you have the `c' library (-lc). */
+#undef HAVE_LIBC
+
+/* Define to 1 if you have the `cam' library (-lcam). */
+#undef HAVE_LIBCAM
+
+/* Define to 1 if you have the `curses' library (-lcurses). */
+#undef HAVE_LIBCURSES
+
+/* Define to 1 if you have the `cur_colr' library (-lcur_colr). */
+#undef HAVE_LIBCUR_COLR
+
+/* Define to 1 if you have the <libc.h> header file. */
+#undef HAVE_LIBC_H
+
+/* Define to 1 if you have the `db' library (-ldb). */
+#undef HAVE_LIBDB
+
+/* Define to 1 if you have the `dbm' library (-ldbm). */
+#undef HAVE_LIBDBM
+
+/* Define to 1 if you have the `gdbm' library (-lgdbm). */
+#undef HAVE_LIBGDBM
+
+/* Define to 1 if you have the `intl' library (-lintl). */
+#undef HAVE_LIBINTL
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `ncurses' library (-lncurses). */
+#undef HAVE_LIBNCURSES
+
+/* Define to 1 if you have the `ndbm' library (-lndbm). */
+#undef HAVE_LIBNDBM
+
+/* 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 `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the `sun' library (-lsun). */
+#undef HAVE_LIBSUN
+
+/* Define to 1 if you have the `termcap' library (-ltermcap). */
+#undef HAVE_LIBTERMCAP
+
+/* Define to 1 if you have the `vtblc' library (-lvtblc). */
+#undef HAVE_LIBVTBLC
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to enable Linux tape-changer support. */
+#undef HAVE_LINUX_LIKE_SCSI
+
+/* Define to 1 if you have the <linux/zftape.h> header file. */
+#undef HAVE_LINUX_ZFTAPE_H
+
+/* Define to 1 if you have the `listen' function. */
+#undef HAVE_LISTEN
+
+/* Define if listen is declared. */
+#undef HAVE_LISTEN_DECL
+
+/* Define to 1 if you have the `lstat' function. */
+#undef HAVE_LSTAT
+
+/* Define if lstat is declared. */
+#undef HAVE_LSTAT_DECL
+
+/* Define to 1 if you have the `malloc' function. */
+#undef HAVE_MALLOC
+
+/* Define if malloc is declared. */
+#undef HAVE_MALLOC_DECL
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define if memmove is declared. */
+#undef HAVE_MEMMOVE_DECL
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define if memset is declared. */
+#undef HAVE_MEMSET_DECL
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define to 1 if you have the `mktemp' function. */
+#undef HAVE_MKTEMP
+
+/* Define if mktemp is declared. */
+#undef HAVE_MKTEMP_DECL
+
+/* Define to 1 if you have the `mktime' function. */
+#undef HAVE_MKTIME
+
+/* Define if mktime is declared. */
+#undef HAVE_MKTIME_DECL
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the <mntent.h> header file. */
+#undef HAVE_MNTENT_H
+
+/* Define to 1 if you have the <mnttab.h> header file. */
+#undef HAVE_MNTTAB_H
+
+/* Define if the mtget structure has an mt_blkno field */
+#undef HAVE_MT_BLKNO
+
+/* Define if the mtget structure has an mt_dsreg field */
+#undef HAVE_MT_DSREG
+
+/* Define if the mtget structure has an mt_erreg field */
+#undef HAVE_MT_ERREG
+
+/* Define if the mtget structure has an mt_fileno field */
+#undef HAVE_MT_FILENO
+
+/* Define if the mtget structure has an mt_flags field */
+#undef HAVE_MT_FLAGS
+
+/* Define to 1 if you have the <ndbm.h> header file. */
+#undef HAVE_NDBM_H
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in_systm.h> header file. */
+#undef HAVE_NETINET_IN_SYSTM_H
+
+/* Define to 1 if you have the <netinet/ip.h> header file. */
+#undef HAVE_NETINET_IP_H
+
+/* Define to 1 if you have the `on_exit' function. */
+#undef HAVE_ON_EXIT
+
+/* Define to 1 if you have the `openlog' function. */
+#undef HAVE_OPENLOG
+
+/* Define if openlog is declared. */
+#undef HAVE_OPENLOG_DECL
+
+/* Define to 1 if you have the `pclose' function. */
+#undef HAVE_PCLOSE
+
+/* Define if pclose is declared. */
+#undef HAVE_PCLOSE_DECL
+
+/* Define to 1 if you have the `perror' function. */
+#undef HAVE_PERROR
+
+/* Define if perror is declared. */
+#undef HAVE_PERROR_DECL
+
+/* Define to 1 if you have the `printf' function. */
+#undef HAVE_PRINTF
+
+/* Define if printf is declared. */
+#undef HAVE_PRINTF_DECL
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the `puts' function. */
+#undef HAVE_PUTS
+
+/* Define if puts is declared. */
+#undef HAVE_PUTS_DECL
+
+/* Define to 1 if you have the <readline.h> header file. */
+#undef HAVE_READLINE_H
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+#undef HAVE_READLINE_HISTORY_H
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+#undef HAVE_READLINE_READLINE_H
+
+/* Define to 1 if you have the `realloc' function. */
+#undef HAVE_REALLOC
+
+/* Define if realloc is declared. */
+#undef HAVE_REALLOC_DECL
+
+/* Define to 1 if you have the `recvfrom' function. */
+#undef HAVE_RECVFROM
+
+/* Define if recvfrom is declared. */
+#undef HAVE_RECVFROM_DECL
+
+/* Define to 1 if you have the `remove' function. */
+#undef HAVE_REMOVE
+
+/* Define if remove is declared. */
+#undef HAVE_REMOVE_DECL
+
+/* Define to 1 if you have the `rename' function. */
+#undef HAVE_RENAME
+
+/* Define if rename is declared. */
+#undef HAVE_RENAME_DECL
+
+/* Define to 1 if you have the `rewind' function. */
+#undef HAVE_REWIND
+
+/* Define if rewind is declared. */
+#undef HAVE_REWIND_DECL
+
+/* Define to 1 if you have the `rmdir' function. */
+#undef HAVE_RMDIR
+
+/* Define to 1 if you have the `ruserok' function. */
+#undef HAVE_RUSEROK
+
+/* Define if ruserok is declared. */
+#undef HAVE_RUSEROK_DECL
+
+/* Define to 1 if you have the <scsi/scsi_ioctl.h> header file. */
+#undef HAVE_SCSI_SCSI_IOCTL_H
+
+/* Define to 1 if you have the <scsi/sg.h> header file. */
+#undef HAVE_SCSI_SG_H
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define if select is declared. */
+#undef HAVE_SELECT_DECL
+
+/* Define to 1 if you have the `sendto' function. */
+#undef HAVE_SENDTO
+
+/* Define if sendto is declared. */
+#undef HAVE_SENDTO_DECL
+
+/* Define to 1 if you have the `setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define if setegid is declared. */
+#undef HAVE_SETEGID_DECL
+
+/* Define to 1 if you have the `seteuid' function. */
+#undef HAVE_SETEUID
+
+/* Define if seteuid is declared. */
+#undef HAVE_SETEUID_DECL
+
+/* Define to 1 if you have the `setmntent' function. */
+#undef HAVE_SETMNTENT
+
+/* Define to 1 if you have the `setpgid' function. */
+#undef HAVE_SETPGID
+
+/* Define if setpgid is declared. */
+#undef HAVE_SETPGID_DECL
+
+/* Define to 1 if you have the `setpgrp' function. */
+#undef HAVE_SETPGRP
+
+/* Define if setpgrp is declared. */
+#undef HAVE_SETPGRP_DECL
+
+/* Define to 1 if you have the `setresgid' function. */
+#undef HAVE_SETRESGID
+
+/* Define if setresgid is declared. */
+#undef HAVE_SETRESGID_DECL
+
+/* Define to 1 if you have the `setresuid' function. */
+#undef HAVE_SETRESUID
+
+/* Define if setresuid is declared. */
+#undef HAVE_SETRESUID_DECL
+
+/* Define to 1 if you have the `setsockopt' function. */
+#undef HAVE_SETSOCKOPT
+
+/* Define if setsockopt is declared. */
+#undef HAVE_SETSOCKOPT_DECL
+
+/* Define to 1 if you have the `shmat' function. */
+#undef HAVE_SHMAT
+
+/* Define if shmat is declared. */
+#undef HAVE_SHMAT_DECL
+
+/* Define to 1 if you have the `shmctl' function. */
+#undef HAVE_SHMCTL
+
+/* Define if shmctl is declared. */
+#undef HAVE_SHMCTL_DECL
+
+/* Define to 1 if you have the `shmdt' function. */
+#undef HAVE_SHMDT
+
+/* Define if shmdt is declared. */
+#undef HAVE_SHMDT_DECL
+
+/* Define to 1 if you have the `shmget' function. */
+#undef HAVE_SHMGET
+
+/* Define if shmget is declared. */
+#undef HAVE_SHMGET_DECL
+
+/* Define to 1 if you have the `shquote' function. */
+#undef HAVE_SHQUOTE
+
+/* Define if shquote is declared. */
+#undef HAVE_SHQUOTE_DECL
+
+/* Define to 1 if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the `sigemptyset' function. */
+#undef HAVE_SIGEMPTYSET
+
+/* Define to 1 if you have the `sigvec' function. */
+#undef HAVE_SIGVEC
+
+/* Define to 1 if you have the `snprintf' function. */
+#undef HAVE_SNPRINTF
+
+/* Define if snprintf is declared. */
+#undef HAVE_SNPRINTF_DECL
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Define to 1 if you have the `socketpair' function. */
+#undef HAVE_SOCKETPAIR
+
+/* Define if socketpair is declared. */
+#undef HAVE_SOCKETPAIR_DECL
+
+/* Define if socket is declared. */
+#undef HAVE_SOCKET_DECL
+
+/* Define to enable Solaris tape-changer support */
+#undef HAVE_SOLARIS_LIKE_SCSI
+
+/* Define to 1 if you have the `sscanf' function. */
+#undef HAVE_SSCANF
+
+/* Define if sscanf is declared. */
+#undef HAVE_SSCANF_DECL
+
+/* Define to 1 if you have the `statfs' function. */
+#undef HAVE_STATFS
+
+/* Define to 1 if you have the `statvfs' function. */
+#undef HAVE_STATVFS
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if strcasecmp is declared. */
+#undef HAVE_STRCASECMP_DECL
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define if strerror is declared. */
+#undef HAVE_STRERROR_DECL
+
+/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_STRFTIME
+
+/* Define if strftime is declared. */
+#undef HAVE_STRFTIME_DECL
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define if strncasecmp is declared. */
+#undef HAVE_STRNCASECMP_DECL
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define if the database header declares struct datum. */
+#undef HAVE_STRUCT_DATUM
+
+/* Define to 1 if you have the `syslog' function. */
+#undef HAVE_SYSLOG
+
+/* Define if syslog is declared. */
+#undef HAVE_SYSLOG_DECL
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the `system' function. */
+#undef HAVE_SYSTEM
+
+/* Define if system is declared. */
+#undef HAVE_SYSTEM_DECL
+
+/* Define if SysV shared-memory functions are available. */
+#undef HAVE_SYSVSHM
+
+/* Define to 1 if you have the <sys/chio.h> header file. */
+#undef HAVE_SYS_CHIO_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/dsreq.h> header file. */
+#undef HAVE_SYS_DSREQ_H
+
+/* Define to 1 if you have the <sys/fcntl.h> header file. */
+#undef HAVE_SYS_FCNTL_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/gscdds.h> header file. */
+#undef HAVE_SYS_GSCDDS_H
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define to 1 if you have the <sys/ipc.h> header file. */
+#undef HAVE_SYS_IPC_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/mntent.h> header file. */
+#undef HAVE_SYS_MNTENT_H
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#undef HAVE_SYS_MOUNT_H
+
+/* Define to 1 if you have the <sys/mtio.h> header file. */
+#undef HAVE_SYS_MTIO_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/scarray.h> header file. */
+#undef HAVE_SYS_SCARRAY_H
+
+/* Define to 1 if you have the <sys/scsiio.h> header file. */
+#undef HAVE_SYS_SCSIIO_H
+
+/* Define to 1 if you have the <sys/scsi.h> header file. */
+#undef HAVE_SYS_SCSI_H
+
+/* Define to 1 if you have the <sys/scsi/impl/uscsi.h> header file. */
+#undef HAVE_SYS_SCSI_IMPL_USCSI_H
+
+/* Define to 1 if you have the <sys/scsi/scsi/ioctl.h> header file. */
+#undef HAVE_SYS_SCSI_SCSI_IOCTL_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/shm.h> header file. */
+#undef HAVE_SYS_SHM_H
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#undef HAVE_SYS_STATFS_H
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#undef HAVE_SYS_STATVFS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/tape.h> header file. */
+#undef HAVE_SYS_TAPE_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/vfstab.h> header file. */
+#undef HAVE_SYS_VFSTAB_H
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+#undef HAVE_SYS_VFS_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the `time' function. */
+#undef HAVE_TIME
+
+/* Define if time is declared. */
+#undef HAVE_TIME_DECL
+
+/* Define to 1 if you have the `tolower' function. */
+#undef HAVE_TOLOWER
+
+/* Define if tolower is declared. */
+#undef HAVE_TOLOWER_DECL
+
+/* Define to 1 if you have the `toupper' function. */
+#undef HAVE_TOUPPER
+
+/* Define if toupper is declared. */
+#undef HAVE_TOUPPER_DECL
+
+/* Define if gettimeofday takes two arguments. */
+#undef HAVE_TWO_ARG_GETTIMEOFDAY
+
+/* Define to 1 if you have the `ungetc' function. */
+#undef HAVE_UNGETC
+
+/* Define if ungetc is declared. */
+#undef HAVE_UNGETC_DECL
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if the compiler support unsigned long constants. */
+#undef HAVE_UNSIGNED_LONG_CONSTANTS
+
+/* Define to 1 if the system has the type `unsigned long long'. */
+#undef HAVE_UNSIGNED_LONG_LONG
+
+/* Define to 1 if you have the `vfprintf' function. */
+#undef HAVE_VFPRINTF
+
+/* Define if vfprintf is declared. */
+#undef HAVE_VFPRINTF_DECL
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Define if vprintf is declared. */
+#undef HAVE_VPRINTF_DECL
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#undef HAVE_VSNPRINTF
+
+/* Define if vsnprintf is declared. */
+#undef HAVE_VSNPRINTF_DECL
+
+/* Define to 1 if you have the `vsprintf' function. */
+#undef HAVE_VSPRINTF
+
+/* Define if vsprintf is declared. */
+#undef HAVE_VSPRINTF_DECL
+
+/* Define to 1 if you have the <vtblc.h> header file. */
+#undef HAVE_VTBLC_H
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define to 1 if you have the <wait.h> header file. */
+#undef HAVE_WAIT_H
+
+/* Define if limits.h defines _POSIX2_RE_DUP_MAX. */
+#undef HAVE__POSIX2_RE_DUP_MAX
+
+/* Define on Cygwin. */
+#undef IGNORE_FSTAB
+
+/* Define on Cygwin. */
+#undef IGNORE_TAR_ERRORS
+
+/* Define on Cygwin. */
+#undef IGNORE_UID_CHECK
+
+/* The name for the Kerberized Amanda service. */
+#undef KAMANDA_SERVICE_NAME
+
+/* Enable Kerberos security. */
+#undef KRB4_SECURITY
+
+/* Command for starting printing jobs. */
+#undef LPRCMD
+
+/* LPRCMD switch for specifying a printer name. */
+#undef LPRFLAG
+
+/* Define to a program that understands -s "subject" user < message_file */
+#undef MAILER
+
+/* Maximum size of a tape block in KBytes. */
+#undef MAX_TAPE_BLOCK_KB
+
+/* Defined to the switch to be used when invoking mt to specify the * tape
+   device. */
+#undef MT_FILE_FLAG
+
+/* Define on Cygwin. */
+#undef NEED_PATH_ENV
+
+/* Define if we have to reset tape offsets when reacing 2GB. */
+#undef NEED_RESETOFS
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the prefix for raw disk devices, commonly /dev/r or /dev/rdsk/ */
+#undef RDEV_PREFIX
+
+/* Define the location of the ufsrestore or restore program. */
+#undef RESTORE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define the location of smbclient for backing up Samba PC clients. */
+#undef SAMBA_CLIENT
+
+/* Not the actual samba version, just a number that should be increased
+   whenever we start to rely on a new samba feature. */
+#undef SAMBA_VERSION
+
+/* Define to type of select arguments. */
+#undef SELECT_ARG_TYPE
+
+/* The Kerberos server instance. */
+#undef SERVER_HOST_INSTANCE
+
+/* The Kerberos server key file. */
+#undef SERVER_HOST_KEY_FILE
+
+/* The Kerberos server principle. */
+#undef SERVER_HOST_PRINCIPLE
+
+/* A suffix that will be appended to service names. * Useful for testing in
+   parallel with a working version. */
+#undef SERVICE_SUFFIX
+
+/* Define to 1 if the `setpgrp' function takes no argument. */
+#undef SETPGRP_VOID
+
+/* Define to type of shmget() function argument. */
+#undef SHM_ARG_TYPE
+
+/* The size of a `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of a `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of a `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of a `void*', as computed by sizeof. */
+#undef SIZEOF_VOIDP
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+       STACK_DIRECTION > 0 => grows toward higher addresses
+       STACK_DIRECTION < 0 => grows toward lower addresses
+       STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define on OSF1. */
+#undef STATFS_OSF1
+
+/* Define on SCO OS5. */
+#undef STATFS_SCO_OS5
+
+/* Define on Ultrix. */
+#undef STATFS_ULTRIX
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* A comma-separated list of two integers, determining the minimum and maximum
+   unreserved TCP port numbers sockets should be bound to. */
+#undef TCPPORTRANGE
+
+/* Define to enable the text-based database format. */
+#undef TEXTDB
+
+/* The Kerberos ticket lifetime. */
+#undef TICKET_LIFETIME
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* A comma-separated list of two integers, determining the minimum and maximum
+   reserved UDP port numbers sockets should be bound to. */
+#undef UDPPORTRANGE
+
+/* Define as any optional arguments to get UNCOMPRESS_PATH to uncompress. */
+#undef UNCOMPRESS_OPT
+
+/* Define as the exact path to the gzip or compress command. */
+#undef UNCOMPRESS_PATH
+
+/* Define if you want to use the .amandahosts for BSD security. */
+#undef USE_AMANDAHOSTS
+
+/* Define to enable dbm databases. */
+#undef USE_DBM_H
+
+/* Define to enable db databases. */
+#undef USE_DB_H
+
+/* Define to use flock for file locking. */
+#undef USE_FLOCK
+
+/* Define for backups being done on a multiple networks and FQDNs are used. */
+#undef USE_FQDN
+
+/* Define to enable gdbm databases. */
+#undef USE_GDBM_H
+
+/* Define to use a hard-link based approach for file locking. */
+#undef USE_LNLOCK
+
+/* Define to use lockf for file locking. */
+#undef USE_LOCKF
+
+/* Define to enable ndbm databases. */
+#undef USE_NDBM_H
+
+/* Define to use Posix fcntl for file locking. */
+#undef USE_POSIX_FCNTL
+
+/* Define if you want to use amqde instead of gnutar for estimates */
+#undef USE_QUICK_AND_DIRTY_ESTIMATES
+
+/* Define to invoke rundump (setuid-root) instead of DUMP program directly. */
+#undef USE_RUNDUMP
+
+/* Define to have programs use version suffixes when calling other programs.
+   */
+#undef USE_VERSION_SUFFIXES
+
+/* Define on UnixWare. */
+#undef UWARE_TAPEIO
+
+/* Define the location of the vdump program. */
+#undef VDUMP
+
+/* Version number of package */
+#undef VERSION
+
+/* Define the location of the vrestore program. */
+#undef VRESTORE
+
+/* Define the location of the vxdump program on HPUX and SINIX hosts or on *
+   other hosts where the Veritas filesystem (vxfs) has been installed. */
+#undef VXDUMP
+
+/* Define the location of the vxrestore program on HPUX and SINIX hosts or on
+   * other hosts where the Veritas filesystem (vxfs) has been installed. */
+#undef VXRESTORE
+
+/* Defined if wait() puts the status in a union wait instead of int. */
+#undef WAIT_USES_UNION
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
+/* Define on XENIX/ISC. */
+#undef XENIX_TAPEIO
+
+/* Define the location of the xfsdump program on Irix hosts. */
+#undef XFSDUMP
+
+/* Define the location of the xfsrestore program on Irix hosts. */
+#undef XFSRESTORE
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+   `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Directory in which user binaries should be installed. */
+#undef bindir
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
+/* Directory in which internal binaries should be installed. */
+#undef libexecdir
+
+/* Directory in which man-pages should be installed */
+#undef mandir
+
+/* Define to `long' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Directory in which administrator binaries should be installed. */
+#undef sbindir
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define if socklen_t is not a standard system type */
+#undef socklen_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to empty if the compiler does not support volatile. */
+#undef volatile
diff --git a/config/config.sub b/config/config.sub
new file mode 100755 (executable)
index 0000000..ba33103
--- /dev/null
@@ -0,0 +1,1549 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2004-03-12'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       1750a | 580 \
+       | a29k \
+       | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+       | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+       | am33_2.0 \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+       | c4x | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k | iq2000 \
+       | m32r | m32rle | m68000 | m68k | m88k | mcore \
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
+       | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el \
+       | mips64vr4300 | mips64vr4300el \
+       | mips64vr5000 | mips64vr5000el \
+       | mipsisa32 | mipsisa32el \
+       | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa64 | mipsisa64el \
+       | mipsisa64r2 | mipsisa64r2el \
+       | mipsisa64sb1 | mipsisa64sb1el \
+       | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | msp430 \
+       | ns16k | ns32k \
+       | openrisc | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic4x | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xstormy16 | xtensa \
+       | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       580-* \
+       | a29k-* \
+       | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+       | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+       | avr-* \
+       | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | clipper-* | cydra-* \
+       | d10v-* | d30v-* | dlx-* \
+       | elxsi-* \
+       | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+       | h8300-* | h8500-* \
+       | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | i*86-* | i860-* | i960-* | ia64-* \
+       | ip2k-* | iq2000-* \
+       | m32r-* | m32rle-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | mcore-* \
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* \
+       | mips64vr5000-* | mips64vr5000el-* \
+       | mipsisa32-* | mipsisa32el-* \
+       | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa64-* | mipsisa64el-* \
+       | mipsisa64r2-* | mipsisa64r2el-* \
+       | mipsisa64sb1-* | mipsisa64sb1el-* \
+       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipstx39-* | mipstx39el-* \
+       | msp430-* \
+       | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+       | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+       | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       abacus)
+               basic_machine=abacus-unknown
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amd64)
+               basic_machine=x86_64-pc
+               ;;
+       amd64-*)
+               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       c90)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | j90)
+               basic_machine=j90-cray
+               os=-unicos
+               ;;
+       cr16c)
+               basic_machine=cr16c-unknown
+               os=-elf
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       crx)
+               basic_machine=crx-unknown
+               os=-elf
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       decsystem10* | dec10*)
+               basic_machine=pdp10-dec
+               os=-tops10
+               ;;
+       decsystem20* | dec20*)
+               basic_machine=pdp10-dec
+               os=-tops20
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nv1)
+               basic_machine=nv1-cray
+               os=-unicosmp
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       or32 | or32-*)
+               basic_machine=or32-unknown
+               os=-coff
+               ;;
+       os400)
+               basic_machine=powerpc-ibm
+               os=-os400
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+       pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon | athlon_*)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2 | pentiumiii | pentium3)
+               basic_machine=i686-pc
+               ;;
+       pentium4)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentium4-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64)  basic_machine=powerpc64-unknown
+               ;;
+       ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+               basic_machine=powerpc64le-unknown
+               ;;
+       ppc64le-* | powerpc64little-*)
+               basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       s390 | s390-*)
+               basic_machine=s390-ibm
+               ;;
+       s390x | s390x-*)
+               basic_machine=s390x-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sb1)
+               basic_machine=mipsisa64sb1-unknown
+               ;;
+       sb1el)
+               basic_machine=mipsisa64sb1el-unknown
+               ;;
+       sei)
+               basic_machine=mips-sei
+               os=-seiux
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparclite-wrs | simso-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=alphaev5-cray
+               os=-unicos
+               ;;
+       t90)
+               basic_machine=t90-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tic55x | c55x*)
+               basic_machine=tic55x-unknown
+               os=-coff
+               ;;
+       tic6x | c6x*)
+               basic_machine=tic6x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       toad1)
+               basic_machine=pdp10-xkl
+               os=-tops20
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       tpf)
+               basic_machine=s390x-ibm
+               os=-tpf
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+               basic_machine=sh-unknown
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparc | sparcv8 | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+       cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+             | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+             | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+             | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+             | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+             | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto-qnx*)
+               ;;
+       -nto*)
+               os=`echo $os | sed -e 's|nto|nto-qnx|'`
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux-dietlibc)
+               os=-linux-dietlibc
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+        -os400*)
+               os=-os400
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -syllable*)
+               os=-syllable
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -nova*)
+               os=-rtmk-nova
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+        -tpf*)
+               os=-tpf
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -aros*)
+               os=-aros
+               ;;
+       -kaos*)
+               os=-kaos
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+       # This must come before the *-dec entry.
+       pdp10-*)
+               os=-tops20
+               ;;
+       pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       or32-*)
+               os=-coff
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+       *-gould)
+               os=-sysv
+               ;;
+       *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+       *-sgi)
+               os=-irix
+               ;;
+       *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -os400*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -tpf*)
+                               vendor=ibm
+                               ;;
+                       -vxsim* | -vxworks* | -windiss*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+                       -vos*)
+                               vendor=stratus
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config/depcomp b/config/depcomp
new file mode 100755 (executable)
index 0000000..25bdb18
--- /dev/null
@@ -0,0 +1,526 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2004-04-25.13
+
+# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit 0
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit 0
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+   dir=`echo "$object" | sed 's,/.*$,/,'`
+   if test "$dir" = "$object"; then
+      dir=
+   fi
+   # FIXME: should be _deps on DOS.
+   depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # Dependencies are output in .lo.d with libtool 1.4.
+      # They are output in .o.d with libtool 1.5.
+      tmpdepfile1="$dir.libs/$base.lo.d"
+      tmpdepfile2="$dir.libs/$base.o.d"
+      tmpdepfile3="$dir.libs/$base.d"
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1="$dir$base.o.d"
+      tmpdepfile2="$dir$base.d"
+      tmpdepfile3="$dir$base.d"
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   elif test -f "$tmpdepfile2"; then
+      tmpdepfile="$tmpdepfile2"
+   else
+      tmpdepfile="$tmpdepfile3"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[   ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
+  echo "       " >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/config/install-sh b/config/install-sh
new file mode 100755 (executable)
index 0000000..e9de238
--- /dev/null
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# 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 M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/config/libtool.m4i b/config/libtool.m4i
new file mode 100644 (file)
index 0000000..16f90d7
--- /dev/null
@@ -0,0 +1,5943 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+## Copyright 1996, 1997, 1998, 1999, 2000, 2001
+## Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 47 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+m4_ifdef([AC_PROVIDE_IFELSE],
+         [],
+         [m4_define([AC_PROVIDE_IFELSE],
+                [m4_ifdef([AC_PROVIDE_$1],
+                          [$2], [$3])])])
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+  AC_PROVIDE_IFELSE([AC_PROG_CXX],
+    [AC_LIBTOOL_CXX],
+    [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+  ])])
+dnl And a similar setup for Fortran 77 support
+  AC_PROVIDE_IFELSE([AC_PROG_F77],
+    [AC_LIBTOOL_F77],
+    [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+  AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+    [AC_LIBTOOL_GCJ],
+    [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+      [AC_LIBTOOL_GCJ],
+      [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+       [AC_LIBTOOL_GCJ],
+      [ifdef([AC_PROG_GCJ],
+            [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([A][M_PROG_GCJ],
+            [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([LT_AC_PROG_GCJ],
+            [define([LT_AC_PROG_GCJ],
+               defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
+])])# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+AC_LIBTOOL_SYS_MAX_CMD_LEN
+AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+AC_LIBTOOL_OBJDIR
+
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+_LT_AC_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
+
+# Same as above, but do not quote variable references.
+[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    AC_PATH_MAGIC
+  fi
+  ;;
+esac
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+       [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+AC_ARG_WITH([pic],
+    [AC_HELP_STRING([--with-pic],
+       [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+AC_LIBTOOL_LANG_C_CONFIG
+_LT_AC_TAGCONFIG
+])# AC_LIBTOOL_SETUP
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+AC_DEFUN([_LT_AC_SYS_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_AC_SYS_COMPILER
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
+[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+AC_DEFUN([_LT_AC_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+            [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+        [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[_LT_AC_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+[$]*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+        test "X$echo_testing_string" = "X$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+         then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "[$]0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+])])# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+AC_DEFUN([_LT_AC_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+       [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+  ])
+esac
+
+need_locks="$enable_libtool_lock"
+
+])# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#              [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+  ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   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
+     if test ! -s conftest.err; then
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$5], , :, [$5])
+else
+    ifelse([$6], , :, [$6])
+fi
+])# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                          [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
+[AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+     else
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$4], , :, [$4])
+else
+    ifelse([$5], , :, [$5])
+fi
+])# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
+[# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+ *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+              = "XX$teststring") >/dev/null 2>&1 &&
+           new_result=`expr "X$teststring" : ".*" 2>&1` &&
+           lt_cv_sys_max_cmd_len=$new_result &&
+           test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+])# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)dnl
+])# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}]
+EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_unknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+               [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+   ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+         [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+           [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+       [AC_CHECK_FUNC([dlopen],
+             [lt_cv_dlopen="dlopen"],
+         [AC_CHECK_LIB([dl], [dlopen],
+               [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+           [AC_CHECK_LIB([svld], [dlopen],
+                 [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+             [AC_CHECK_LIB([dld], [dld_link],
+                   [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+             ])
+           ])
+         ])
+       ])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+         lt_cv_dlopen_self, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+           lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+         lt_cv_dlopen_self_static, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+           lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+])
+])# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
+[AC_REQUIRE([_LT_AC_LOCK])dnl
+
+hard_links="nottested"
+if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+AC_DEFUN([AC_LIBTOOL_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+])# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_AC_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
+   test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \
+   test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_AC_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
+[striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         AC_MSG_RESULT([yes])
+       else
+  AC_MSG_RESULT([no])
+fi
+       ;;
+   *)
+  AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+])# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
+[AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+AC_DEFUN([_LT_AC_TAGCONFIG],
+[AC_ARG_WITH([tags],
+    [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
+        [include additional configurations @<:@automatic@:>@])],
+    [tagnames="$withval"])
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    AC_MSG_WARN([output file `$ofile' does not exist])
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+    else
+      AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+    fi
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
+    "") ;;
+    *)  AC_MSG_ERROR([invalid tag name: $tagname])
+       ;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      AC_MSG_ERROR([tag name \"$tagname\" already exists])
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+       if test -n "$CXX" && test "X$CXX" != "Xno"; then
+         AC_LIBTOOL_LANG_CXX_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      F77)
+       if test -n "$F77" && test "X$F77" != "Xno"; then
+         AC_LIBTOOL_LANG_F77_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      GCJ)
+       if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+         AC_LIBTOOL_LANG_GCJ_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      RC)
+       AC_LIBTOOL_LANG_RC_CONFIG
+       ;;
+
+      *)
+       AC_MSG_ERROR([Unsupported tag name: $tagname])
+       ;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    AC_MSG_ERROR([unable to update list of available tagged configurations.])
+  fi
+fi
+])# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN],
+ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([shared],
+    [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+       [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_shared=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
+])# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+#- set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)
+])# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([static],
+    [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+       [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_static=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]AC_ENABLE_STATIC_DEFAULT)
+])# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)
+])# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([fast-install],
+    [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_fast_install=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
+])# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)
+])# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)
+])# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+   [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])])
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+])# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+    [AC_HELP_STRING([--with-gnu-ld],
+       [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+])# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case "$host_cpu" in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  case $host_cpu in
+  alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*)
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+])# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm="$ac_dir/${ac_tool_prefix}nm"
+    if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+      */dev/null* | *'Invalid file or object type'*)
+       lt_cv_path_NM="$tmp_nm -B"
+       break
+        ;;
+      *)
+       case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+       */dev/null*)
+         lt_cv_path_NM="$tmp_nm -p"
+         break
+         ;;
+       *)
+         lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+         ;;
+       esac
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+])# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+])# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments.  Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
+# DIRECTORY is not provided, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments.  Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
+# DIRECTORY is not provided and an installed libltdl is not found, it is
+# assumed to be `libltdl'.  LIBLTDL will be prefixed with '${top_builddir}/'
+# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
+# quotes!).  If your package is not flat and you're not using automake,
+# define top_builddir and top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, lt_dlinit,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    LTDLINCL=
+  fi
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX],
+[AC_REQUIRE([_LT_AC_LANG_CXX])
+])# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+AC_DEFUN([_LT_AC_LANG_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
+])# _LT_AC_LANG_CXX
+
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+AC_DEFUN([AC_LIBTOOL_F77],
+[AC_REQUIRE([_LT_AC_LANG_F77])
+])# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+AC_DEFUN([_LT_AC_LANG_F77],
+[AC_REQUIRE([AC_PROG_F77])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
+])# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],
+[AC_REQUIRE([_LT_AC_LANG_GCJ])
+])# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+AC_DEFUN([_LT_AC_LANG_GCJ],
+[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+    [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+      [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+        [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+          [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
+])# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# --------------
+# enable support for Windows resource files
+AC_DEFUN([AC_LIBTOOL_RC],
+[AC_REQUIRE([LT_AC_PROG_RC])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
+])# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
+AC_DEFUN([_LT_AC_LANG_C_CONFIG],
+[lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+_LT_AC_SYS_COMPILER
+
+#
+# Check for any special shared library compilation flags.
+#
+_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)=
+if test "$GCC" = no; then
+  case $host_os in
+  sco3.2v5*)
+    _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf'
+    ;;
+  esac
+fi
+if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then
+  AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries])
+  if echo "$old_CC $old_CFLAGS " | grep "[[    ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[        ]]" >/dev/null; then :
+  else
+    AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure])
+    _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no
+  fi
+fi
+
+
+#
+# Check to make sure the static flag actually works.
+#
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works],
+  _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+  $_LT_AC_TAGVAR(lt_prog_compiler_static, $1),
+  [],
+  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+# Report which librarie types wil actually be built
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+  darwin* | rhapsody*)
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    output_verbose_link_cmd='echo'
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring'
+    _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag  -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+  else
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+  fi
+    ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
+AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
+[AC_LANG_PUSH(C++)
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Dependencies to place before and after the object being linked:
+_LT_AC_TAGVAR(predep_objects, $1)=
+_LT_AC_TAGVAR(postdep_objects, $1)=
+_LT_AC_TAGVAR(predeps, $1)=
+_LT_AC_TAGVAR(postdeps, $1)=
+_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
+
+# Source file extension for C++ test sources.
+ac_ext=cc
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+else
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+  AC_PROG_LD
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+       grep 'no-whole-archive' > /dev/null; then
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+       for ld_flag in $LDFLAGS; do
+         case $ld_flag in
+         *-brtl*)
+           aix_use_runtimelinking=yes
+           break
+           ;;
+         esac
+       done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    _LT_AC_TAGVAR(archive_cmds, $1)=''
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.[012]|aix4.[012].*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+       collect2name=`${CC} -print-prog-name=collect2`
+       if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+       then
+         # We have reworked collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+       else
+         # We have old collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+       fi
+      esac
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+       shared_flag='-G'
+      else
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag='${wl}-G'
+       else
+         shared_flag='${wl}-bM:SRE'
+       fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      _LT_AC_SYS_LIBPATH_AIX
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+       # Warning - without using the other run time loading flags,
+       # -berok will link without error, but may produce a broken library.
+       _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+       # -bexpall does not export symbols beginning with underscore (_)
+       _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+       # Exported symbols can be pulled into shared objects from archives
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+       _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+       # This is similar to how AIX traditionally builds it's shared libraries.
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+  chorus*)
+    case $cc_basename in
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+    # as there is no search path for DLLs.
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+    _LT_AC_TAGVAR(always_export_symbols, $1)=no
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+       cp $export_symbols $output_objdir/$soname.def;
+      else
+       echo EXPORTS > $output_objdir/$soname.def;
+       cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+  ;;
+
+  darwin* | rhapsody*)
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    lt_int_apple_cc_single_mod=no
+    output_verbose_link_cmd='echo'
+    if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+      lt_int_apple_cc_single_mod=yes
+    fi
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    else
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    fi
+    _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+  else
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+  fi
+    ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      ghcx)
+       # Green Hills C++ Compiler
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  freebsd[12]*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  freebsd-elf*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  freebsd* | kfreebsd*-gnu)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                               # but as the default
+                               # location of the library.
+
+    case $cc_basename in
+    CC)
+      # FIXME: insert proper C++ library support
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    aCC)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      case "$host_cpu" in
+      hppa*64*)
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+        ;;
+      ia64*)
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+        ;;
+      *)
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        ;;
+      esac
+    fi
+    case "$host_cpu" in
+    hppa*64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+    ia64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    *)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      aCC)
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       esac
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test $with_gnu_ld = no; then
+           case "$host_cpu" in
+           ia64*|hppa*64*)
+             _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+             ;;
+           *)
+             _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           esac
+         fi
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC)
+       # SGI C++
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+       # Archives containing C++ object files must be created using
+       # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test "$with_gnu_ld" = no; then
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+         else
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+         fi
+       fi
+       _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+       ;;
+    esac
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+       ;;
+      icpc)
+       # Intel C++
+       with_gnu_ld=yes
+       _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+       ;;
+      cxx)
+       # Compaq C++
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+       runpath_var=LD_RUN_PATH
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+
+       ;;
+      RCC)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      cxx)
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Archives containing C++ object files must be created using
+       # the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
+       ;;
+      RCC)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      cxx)
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+         echo "-hidden">> $lib.exp~
+         $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~
+         $rm $lib.exp'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  sco*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case $cc_basename in
+      CC)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC)
+       # Sun C++ 4.x
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      lcc)
+       # Lucid
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC)
+       # Sun C++ 4.2, 5.x and Centerline C++
+       _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+       case $host_os in
+         solaris2.[0-5] | solaris2.[0-5].*) ;;
+         *)
+           # The C++ compiler is used as linker so we must use $wl
+           # flag to pass the commands to the underlying system
+           # linker.
+           # Supported since Solaris 2.6 (maybe 2.5.1?)
+           _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+           ;;
+       esac
+       _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       # Archives containing C++ object files must be created using
+       # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+       ;;
+      gcx)
+       # Green Hills C++ Compiler
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+       # The C++ compiler must be used to create the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+       ;;
+      *)
+       # GNU C++ compiler with Solaris linker
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+         if $CC --version | grep -v '^2\.7' > /dev/null; then
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         else
+           # g++ 2.7 appears to require `-G' NOT `-shared' on this
+           # platform.
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         fi
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+       fi
+       ;;
+    esac
+    ;;
+  sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC)
+       # NonStop-UX NCC 3.20
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+esac
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$GXX"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_POSTDEP_PREDEP($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+])# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
+int a;
+void foo (void) { a = 0; }
+EOF
+],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+],[$1],[F77],[cat > conftest.$ac_ext <<EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+EOF
+],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+         || test $p = "-R"; then
+        prev=$p
+        continue
+       else
+        prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        case $p in
+        -L* | -R*)
+          # Internal compiler library paths should come after those
+          # provided the user.  The postdeps already come after the
+          # user supplied libs so there is no need to process them.
+          if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
+            _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+          else
+            _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+          fi
+          ;;
+        # The "-l" case would never come before the object being
+        # linked, so don't bother handling this case.
+        esac
+       else
+        if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
+          _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
+        else
+          _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
+        fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+        pre_test_object_deps_done=yes
+        continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
+          _LT_AC_TAGVAR(predep_objects, $1)="$p"
+        else
+          _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
+        fi
+       else
+        if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
+          _LT_AC_TAGVAR(postdep_objects, $1)="$p"
+        else
+          _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
+        fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$rm -f confest.$objext
+
+case " $_LT_AC_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+])# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
+AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
+[AC_REQUIRE([AC_PROG_F77])
+AC_LANG_PUSH(Fortran 77)
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$G77"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
+AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
+AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars.  Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+AC_DEFUN([AC_LIBTOOL_CONFIG],
+[# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    _LT_AC_TAGVAR(compiler, $1) \
+    _LT_AC_TAGVAR(CC, $1) \
+    _LT_AC_TAGVAR(LD, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
+    _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
+    _LT_AC_TAGVAR(old_archive_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
+    _LT_AC_TAGVAR(predep_objects, $1) \
+    _LT_AC_TAGVAR(postdep_objects, $1) \
+    _LT_AC_TAGVAR(predeps, $1) \
+    _LT_AC_TAGVAR(postdeps, $1) \
+    _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
+    _LT_AC_TAGVAR(archive_cmds, $1) \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(postinstall_cmds, $1) \
+    _LT_AC_TAGVAR(postuninstall_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
+    _LT_AC_TAGVAR(allow_undefined_flag, $1) \
+    _LT_AC_TAGVAR(no_undefined_flag, $1) \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
+    _LT_AC_TAGVAR(hardcode_automatic, $1) \
+    _LT_AC_TAGVAR(module_cmds, $1) \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+    _LT_AC_TAGVAR(exclude_expsyms, $1) \
+    _LT_AC_TAGVAR(include_expsyms, $1); do
+
+    case $var in
+    _LT_AC_TAGVAR(old_archive_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(module_cmds, $1) | \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\[$]0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
+    ;;
+  esac
+
+ifelse([$1], [],
+  [cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  AC_MSG_NOTICE([creating $ofile])],
+  [cfgfile="$ofile"])
+
+  cat <<__EOF__ >> "$cfgfile"
+ifelse([$1], [],
+[#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG],
+[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+
+# Is the compiler the GNU C compiler?
+with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
+archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
+module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+
+# Symbols that must always be exported.
+include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+
+ifelse([$1],[],
+[# ### END LIBTOOL CONFIG],
+[# ### END LIBTOOL TAG CONFIG: $tagname])
+
+__EOF__
+
+ifelse([$1],[], [
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+])
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+])# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+
+_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris* | sysv5*)
+  symcode='[[BDRT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[     ]]\($symcode$symcode*\)[[       ]][[    ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+       if grep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+         cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+         $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+         cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$ac_objext conftstm.$ac_objext
+         lt_save_LIBS="$LIBS"
+         lt_save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$ac_objext"
+         CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+         if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+           pipe_works=yes
+         fi
+         LIBS="$lt_save_LIBS"
+         CFLAGS="$lt_save_CFLAGS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
+[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+ ifelse([$1],[CXX],[
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       ;;
+      esac
+      ;;
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+       # All AIX code is PIC.
+       if test "$host_cpu" = ia64; then
+         # AIX 5 now supports IA64 processor
+         _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+       else
+         _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+       fi
+       ;;
+      chorus*)
+       case $cc_basename in
+       cxch68)
+         # Green Hills C++ Compiler
+         # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+         ;;
+       esac
+       ;;
+      dgux*)
+       case $cc_basename in
+         ec++)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           ;;
+         ghcx)
+           # Green Hills C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      freebsd* | kfreebsd*-gnu)
+       # FreeBSD uses GNU C++
+       ;;
+      hpux9* | hpux10* | hpux11*)
+       case $cc_basename in
+         CC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+           if test "$host_cpu" != ia64; then
+             _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+           fi
+           ;;
+         aCC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+           case "$host_cpu" in
+           hppa*64*|ia64*)
+             # +Z the default
+             ;;
+           *)
+             _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+             ;;
+           esac
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      irix5* | irix6* | nonstopux*)
+       case $cc_basename in
+         CC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           # CC pic flag -KPIC is the default.
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      linux*)
+       case $cc_basename in
+         KCC)
+           # KAI C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+           ;;
+         icpc)
+           # Intel C++
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+           ;;
+         cxx)
+           # Compaq C++
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      lynxos*)
+       ;;
+      m88k*)
+       ;;
+      mvs*)
+       case $cc_basename in
+         cxx)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      netbsd*)
+       ;;
+      osf3* | osf4* | osf5*)
+       case $cc_basename in
+         KCC)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+           ;;
+         RCC)
+           # Rational C++ 2.4.1
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         cxx)
+           # Digital/Compaq C++
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      psos*)
+       ;;
+      sco*)
+       case $cc_basename in
+         CC)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      solaris*)
+       case $cc_basename in
+         CC)
+           # Sun C++ 4.2, 5.x and Centerline C++
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+           ;;
+         gcx)
+           # Green Hills C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sunos4*)
+       case $cc_basename in
+         CC)
+           # Sun C++ 4.x
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           ;;
+         lcc)
+           # Lucid
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      tandem*)
+       case $cc_basename in
+         NCC)
+           # NonStop-UX NCC 3.20
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      unixware*)
+       ;;
+      vxworks*)
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+       ;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      ccc*)
+        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn'
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
+    _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1),
+    [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+])
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
+[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ifelse([$1],[CXX],[
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+],[
+  runpath_var=
+  _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+  _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_AC_TAGVAR(archive_cmds, $1)=
+  _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+  _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+  _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_AC_TAGVAR(hardcode_automatic, $1)=no
+  _LT_AC_TAGVAR(module_cmds, $1)=
+  _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(always_export_symbols, $1)=no
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_AC_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=no
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds"
+      fi
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then
+      runpath_var=LD_RUN_PATH
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+       else
+         _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_AC_TAGVAR(archive_cmds, $1)=''
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.[012]|aix4.[012].*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+         else
+         # We have old collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+         fi
+       esac
+       shared_flag='-shared'
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+       if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+       fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        _LT_AC_SYS_LIBPATH_AIX
+        _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+         # -bexpall does not export symbols beginning with underscore (_)
+         _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+         # Exported symbols can be pulled into shared objects from archives
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+         # This is similar to how AIX traditionally builds it's shared libraries.
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      # see comment about different semantics on the GNU ld section
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    bsdi4*)
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      case "$host_os" in
+      rhapsody* | darwin1.[[012]])
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+       ;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+       ;;
+      esac
+       lt_int_apple_cc_single_mod=no
+       output_verbose_link_cmd='echo'
+       if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+         lt_int_apple_cc_single_mod=yes
+       fi
+       if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+       else
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+      ;;
+
+    dgux*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*)
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+         _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+         ;;
+       ia64*)
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+         _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         ;;
+       *)
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+         _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    openbsd*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      else
+       case $host_os in
+        openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+          _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+          ;;
+        *)
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    sco3.2v5*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+      esac
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+        ;;
+       motorola)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[[78]]* | unixware7*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv5*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_AC_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+        then
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+])# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+])# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+  test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+  AC_SUBST(GCJFLAGS)
+])
+
+AC_DEFUN([LT_AC_PROG_RC],
+[AC_CHECK_TOOL(RC, windres, no)
+])
+
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && break
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+SED=$lt_cv_path_SED
+])
+AC_MSG_RESULT([$SED])
+])
diff --git a/config/ltmain.sh b/config/ltmain.sh
new file mode 100644 (file)
index 0000000..70f0b2d
--- /dev/null
@@ -0,0 +1,6422 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+basename="s,^.*/,,g"
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+progname=`echo "$progpath" | $SED $basename`
+modename="$progname"
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.5.6
+TIMESTAMP=" (1.1220.2.94 2004/04/10 16:27:27)"
+
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo A|tr A '\301'` in
+ A) # EBCDIC based system
+  SP2NL="tr '\100' '\n'"
+  NL2SP="tr '\r\n' '\100\100'"
+  ;;
+ *) # Assume ASCII based system
+  SP2NL="tr '\040' '\012'"
+  NL2SP="tr '\015\012' '\040\040'"
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+: ${IFS="      
+"}
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$modename: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit $EXIT_FAILURE
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid () {
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 | \
+       sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
+      if test "X$win32_nmres" = "Ximport" ; then
+        win32_libid_type="x86 archive import"
+      else
+        win32_libid_type="x86 archive static"
+      fi
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $echo $win32_libid_type
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag () {
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+       case $arg in
+         *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       CC_quoted="$CC_quoted $arg"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+       for z in $available_tags; do
+         if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+           # Evaluate the configuration.
+           eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+           CC_quoted=
+           for arg in $CC; do
+           # Double-quote args containing other shell metacharacters.
+           case $arg in
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
+             arg="\"$arg\""
+             ;;
+           esac
+           CC_quoted="$CC_quoted $arg"
+         done
+           case "$@ " in
+             " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
+             # The compiler in the base compile command matches
+             # the one in the tagged configuration.
+             # Assume this is the tagged configuration we want.
+             tagname=$z
+             break
+             ;;
+           esac
+         fi
+       done
+       # If $tagname still isn't set, then no tagged configuration
+       # was found and let the user know that the "--tag" command
+       # line option must be used.
+       if test -z "$tagname"; then
+         $echo "$modename: unable to infer tagged configuration"
+         $echo "$modename: specify a tag with \`--tag'" 1>&2
+         exit $EXIT_FAILURE
+#        else
+#          $echo "$modename: using $tagname tagged configuration"
+       fi
+       ;;
+      esac
+    fi
+}
+# End of Shell function definitions
+#####################################
+
+# Darwin sucks
+eval std_shrext=\"$shrext_cmds\"
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    tag)
+      tagname="$arg"
+      preserve_args="${preserve_args}=$arg"
+
+      # Check whether tagname contains only valid characters
+      case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+       $echo "$progname: invalid tag name: $tagname" 1>&2
+       exit $EXIT_FAILURE
+       ;;
+      esac
+
+      case $tagname in
+      CC)
+       # Don't test for the "default" C tag, as we know, it's there, but
+       # not specially marked.
+       ;;
+      *)
+       if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
+         taglist="$taglist $tagname"
+         # Evaluate the configuration.
+         eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
+       else
+         $echo "$progname: ignoring unknown tag $tagname" 1>&2
+       fi
+       ;;
+      esac
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    $echo
+    $echo "Copyright (C) 2003  Free Software Foundation, Inc."
+    $echo "This is free software; see the source for copying conditions.  There is NO"
+    $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+    exit $EXIT_SUCCESS
+    ;;
+
+  --config)
+    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
+    done
+    exit $EXIT_SUCCESS
+    ;;
+
+  --debug)
+    $echo "$progname: enabling shell trace mode"
+    set -x
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit $EXIT_SUCCESS
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
+  --quiet | --silent)
+    show=:
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --tag) prevopt="--tag" prev=tag ;;
+  --tag=*)
+    set tag "$optarg" ${1+"$@"}
+    shift
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+fi
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+    $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2
+    case $nonopt in
+    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+      mode=link
+      for arg
+      do
+       case $arg in
+       -c)
+          mode=compile
+          break
+          ;;
+       esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+       if test -n "$nonopt"; then
+         $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+       else
+         $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+       fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+
+    for arg
+    do
+      case "$arg_mode" in
+      arg  )
+       # do not "continue".  Instead, add this to base_compile
+       lastarg="$arg"
+       arg_mode=normal
+       ;;
+
+      target )
+       libobj="$arg"
+       arg_mode=normal
+       continue
+       ;;
+
+      normal )
+       # Accept any command-line options.
+       case $arg in
+       -o)
+         if test -n "$libobj" ; then
+           $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         arg_mode=target
+         continue
+         ;;
+
+       -static | -prefer-pic | -prefer-non-pic)
+         later="$later $arg"
+         continue
+         ;;
+
+       -no-suppress)
+         suppress_opt=no
+         continue
+         ;;
+
+       -Xcompiler)
+         arg_mode=arg  #  the next one goes into the "base_compile" arg list
+         continue      #  The current "srcfile" will either be retained or
+         ;;            #  replaced later.  I would guess that would be a bug.
+
+       -Wc,*)
+         args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+         lastarg=
+         save_ifs="$IFS"; IFS=','
+         for arg in $args; do
+           IFS="$save_ifs"
+
+           # Double-quote args containing other shell metacharacters.
+           # Many Bourne shells cannot handle close brackets correctly
+           # in scan sets, so we specify it separately.
+           case $arg in
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
+             arg="\"$arg\""
+             ;;
+           esac
+           lastarg="$lastarg $arg"
+         done
+         IFS="$save_ifs"
+         lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+         # Add the arguments to base_compile.
+         base_compile="$base_compile $lastarg"
+         continue
+         ;;
+
+       * )
+         # Accept the current argument as the source file.
+         # The previous "srcfile" becomes the current argument.
+         #
+         lastarg="$srcfile"
+         srcfile="$arg"
+         ;;
+       esac  #  case $arg
+       ;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      case $lastarg in
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      base_compile="$base_compile $lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      $echo "$modename: you must specify an argument for -Xcompile"
+      exit $EXIT_FAILURE
+      ;;
+    target)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *)
+      # Get the name of the library object.
+      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSifmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.ii) xform=ii ;;
+    *.class) xform=class ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    *.java) xform=java ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -static)
+       build_old_libs=yes
+       continue
+       ;;
+
+      -prefer-pic)
+       pic_mode=yes
+       continue
+       ;;
+
+      -prefer-non-pic)
+       pic_mode=no
+       continue
+       ;;
+      esac
+    done
+
+    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$xdir" = "X$obj"; then
+      xdir=
+    else
+      xdir=$xdir/
+    fi
+    lobj=${xdir}$objdir/$objname
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$progpath" "$lockfile" 2>/dev/null; do
+       $show "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+       $echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+      $echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    $run $rm "$libobj" "${libobj}T"
+
+    # Create a libtool object file (analogous to a ".la" file),
+    # but don't create it if we're doing a dry run.
+    test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+       command="$base_compile $srcfile $pic_flag"
+      else
+       # Don't build PIC code
+       command="$base_compile $srcfile"
+      fi
+
+      if test ! -d "${xdir}$objdir"; then
+       $show "$mkdir ${xdir}$objdir"
+       $run $mkdir ${xdir}$objdir
+       status=$?
+       if test "$status" -ne 0 && test ! -d "${xdir}$objdir"; then
+         exit $status
+       fi
+      fi
+
+      if test -z "$output_obj"; then
+       # Place PIC objects in $objdir
+       command="$command -o $lobj"
+      fi
+
+      $run $rm "$lobj" "$output_obj"
+
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       test -n "$output_obj" && $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+       $show "$mv $output_obj $lobj"
+       if $run $mv $output_obj $lobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Append the name of the PIC object to the libtool object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+        suppress_output=' >/dev/null 2>&1'
+      fi
+    else
+      # No PIC object so indicate it doesn't exist in the libtool
+      # object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+       # Don't build PIC code
+       command="$base_compile $srcfile"
+      else
+       command="$base_compile $srcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+       command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$obj" "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+       $show "$mv $output_obj $obj"
+       if $run $mv $output_obj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+    else
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+    fi
+
+    $run $mv "${libobj}T" "${libobj}"
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    base_compile="$nonopt $@"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static)
+       if test "X$arg" = "X-all-static"; then
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+         fi
+         if test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       else
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       fi
+       build_libtool_libs=no
+       build_old_libs=yes
+       prefer_static_libs=yes
+       break
+       ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+       ;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+       case $prev in
+       output)
+         compile_command="$compile_command @OUTPUT@"
+         finalize_command="$finalize_command @OUTPUT@"
+         ;;
+       esac
+
+       case $prev in
+       dlfiles|dlprefiles)
+         if test "$preload" = no; then
+           # Add the symbol object into the linking commands.
+           compile_command="$compile_command @SYMFILE@"
+           finalize_command="$finalize_command @SYMFILE@"
+           preload=yes
+         fi
+         case $arg in
+         *.la | *.lo) ;;  # We handle these cases below.
+         force)
+           if test "$dlself" = no; then
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         self)
+           if test "$prev" = dlprefiles; then
+             dlself=yes
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+             dlself=yes
+           else
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         *)
+           if test "$prev" = dlfiles; then
+             dlfiles="$dlfiles $arg"
+           else
+             dlprefiles="$dlprefiles $arg"
+           fi
+           prev=
+           continue
+           ;;
+         esac
+         ;;
+       expsyms)
+         export_symbols="$arg"
+         if test ! -f "$arg"; then
+           $echo "$modename: symbol file \`$arg' does not exist"
+           exit $EXIT_FAILURE
+         fi
+         prev=
+         continue
+         ;;
+       expsyms_regex)
+         export_symbols_regex="$arg"
+         prev=
+         continue
+         ;;
+       inst_prefix)
+         inst_prefix_dir="$arg"
+         prev=
+         continue
+         ;;
+       precious_regex)
+         precious_files_regex="$arg"
+         prev=
+         continue
+         ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       objectlist)
+         if test -f "$arg"; then
+           save_arg=$arg
+           moreargs=
+           for fil in `cat $save_arg`
+           do
+#            moreargs="$moreargs $fil"
+             arg=$fil
+             # A libtool-controlled object.
+
+             # Check to see that this really is a libtool object.
+             if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+               pic_object=
+               non_pic_object=
+
+               # Read the .lo file
+               # If there is no directory component, then add one.
+               case $arg in
+               */* | *\\*) . $arg ;;
+               *) . ./$arg ;;
+               esac
+
+               if test -z "$pic_object" || \
+                  test -z "$non_pic_object" ||
+                  test "$pic_object" = none && \
+                  test "$non_pic_object" = none; then
+                 $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+                 exit $EXIT_FAILURE
+               fi
+
+               # Extract subdirectory from the argument.
+               xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+               if test "X$xdir" = "X$arg"; then
+                 xdir=
+               else
+                 xdir="$xdir/"
+               fi
+
+               if test "$pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 pic_object="$xdir$pic_object"
+
+                 if test "$prev" = dlfiles; then
+                   if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+                     dlfiles="$dlfiles $pic_object"
+                     prev=
+                     continue
+                   else
+                     # If libtool objects are unsupported, then we need to preload.
+                     prev=dlprefiles
+                   fi
+                 fi
+
+                 # CHECK ME:  I think I busted this.  -Ossama
+                 if test "$prev" = dlprefiles; then
+                   # Preload the old-style object.
+                   dlprefiles="$dlprefiles $pic_object"
+                   prev=
+                 fi
+
+                 # A PIC object.
+                 libobjs="$libobjs $pic_object"
+                 arg="$pic_object"
+               fi
+
+               # Non-PIC object.
+               if test "$non_pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 non_pic_object="$xdir$non_pic_object"
+
+                 # A standard non-PIC object
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+                 if test -z "$pic_object" || test "$pic_object" = none ; then
+                   arg="$non_pic_object"
+                 fi
+               fi
+             else
+               # Only an error if not doing a dry-run.
+               if test -z "$run"; then
+                 $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+                 exit $EXIT_FAILURE
+               else
+                 # Dry-run case.
+
+                 # Extract subdirectory from the argument.
+                 xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+                 if test "X$xdir" = "X$arg"; then
+                   xdir=
+                 else
+                   xdir="$xdir/"
+                 fi
+
+                 pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+                 non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+                 libobjs="$libobjs $pic_object"
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+               fi
+             fi
+           done
+         else
+           $echo "$modename: link input file \`$save_arg' does not exist"
+           exit $EXIT_FAILURE
+         fi
+         arg=$save_arg
+         prev=
+         continue
+         ;;
+       rpath | xrpath)
+         # We need an absolute path.
+         case $arg in
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
+         *)
+           $echo "$modename: only absolute run-paths are allowed" 1>&2
+           exit $EXIT_FAILURE
+           ;;
+         esac
+         if test "$prev" = rpath; then
+           case "$rpath " in
+           *" $arg "*) ;;
+           *) rpath="$rpath $arg" ;;
+           esac
+         else
+           case "$xrpath " in
+           *" $arg "*) ;;
+           *) xrpath="$xrpath $arg" ;;
+           esac
+         fi
+         prev=
+         continue
+         ;;
+       xcompiler)
+         compiler_flags="$compiler_flags $qarg"
+         prev=
+         compile_command="$compile_command $qarg"
+         finalize_command="$finalize_command $qarg"
+         continue
+         ;;
+       xlinker)
+         linker_flags="$linker_flags $qarg"
+         compiler_flags="$compiler_flags $wl$qarg"
+         prev=
+         compile_command="$compile_command $wl$qarg"
+         finalize_command="$finalize_command $wl$qarg"
+         continue
+         ;;
+       xcclinker)
+         linker_flags="$linker_flags $qarg"
+         compiler_flags="$compiler_flags $qarg"
+         prev=
+         compile_command="$compile_command $qarg"
+         finalize_command="$finalize_command $qarg"
+         continue
+         ;;
+       shrext)
+         shrext_cmds="$arg"
+         prev=
+         continue
+         ;;
+       *)
+         eval "$prev=\"\$arg\""
+         prev=
+         continue
+         ;;
+       esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+       if test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+       continue
+       ;;
+
+      -avoid-version)
+       avoid_version=yes
+       continue
+       ;;
+
+      -dlopen)
+       prev=dlfiles
+       continue
+       ;;
+
+      -dlpreopen)
+       prev=dlprefiles
+       continue
+       ;;
+
+      -export-dynamic)
+       export_dynamic=yes
+       continue
+       ;;
+
+      -export-symbols | -export-symbols-regex)
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+         $echo "$modename: more than one -exported-symbols argument is not allowed"
+         exit $EXIT_FAILURE
+       fi
+       if test "X$arg" = "X-export-symbols"; then
+         prev=expsyms
+       else
+         prev=expsyms_regex
+       fi
+       continue
+       ;;
+
+      -inst-prefix-dir)
+       prev=inst_prefix
+       continue
+       ;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+       case $with_gcc/$host in
+       no/*-*-irix* | /*-*-irix*)
+         compile_command="$compile_command $arg"
+         finalize_command="$finalize_command $arg"
+         ;;
+       esac
+       continue
+       ;;
+
+      -L*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         absdir=`cd "$dir" && pwd`
+         if test -z "$absdir"; then
+           $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         dir="$absdir"
+         ;;
+       esac
+       case "$deplibs " in
+       *" -L$dir "*) ;;
+       *)
+         deplibs="$deplibs -L$dir"
+         lib_search_path="$lib_search_path $dir"
+         ;;
+       esac
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         case :$dllsearchpath: in
+         *":$dir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$dir";;
+         esac
+         ;;
+       esac
+       continue
+       ;;
+
+      -l*)
+       if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+         case $host in
+         *-*-cygwin* | *-*-pw32* | *-*-beos*)
+           # These systems don't actually have a C or math library (as such)
+           continue
+           ;;
+         *-*-mingw* | *-*-os2*)
+           # These systems don't actually have a C library (as such)
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-openbsd* | *-*-freebsd*)
+           # Do not include libc due to us having libc/libc_r.
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C and math libraries are in the System framework
+           deplibs="$deplibs -framework System"
+           continue
+         esac
+       elif test "X$arg" = "X-lc_r"; then
+        case $host in
+        *-*-openbsd* | *-*-freebsd*)
+          # Do not include libc_r directly, use -pthread flag.
+          continue
+          ;;
+        esac
+       fi
+       deplibs="$deplibs $arg"
+       continue
+       ;;
+
+     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+       deplibs="$deplibs $arg"
+       continue
+       ;;
+
+      -module)
+       module=yes
+       continue
+       ;;
+
+      # gcc -m* arguments should be passed to the linker via $compiler_flags
+      # in order to pass architecture information to the linker
+      # (e.g. 32 vs 64-bit).  This may also be accomplished via -Wl,-mfoo
+      # but this is not reliable with gcc because gcc may use -mfoo to
+      # select a different linker, different libraries, etc, while
+      # -Wl,-mfoo simply passes -mfoo to the linker.
+      -m*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+        compile_command="$compile_command $arg"
+        finalize_command="$finalize_command $arg"
+        if test "$with_gcc" = "yes" ; then
+          compiler_flags="$compiler_flags $arg"
+        fi
+        continue
+        ;;
+
+      -shrext)
+       prev=shrext
+       continue
+       ;;
+
+      -no-fast-install)
+       fast_install=no
+       continue
+       ;;
+
+      -no-install)
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         # The PATH hackery in wrapper scripts is required on Windows
+         # in order for the loader to find any dlls it needs.
+         $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+         $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+         fast_install=no
+         ;;
+       *) no_install=yes ;;
+       esac
+       continue
+       ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -objectlist)
+       prev=objectlist
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+       prev=precious_regex
+       continue
+       ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -rpath)
+       prev=rpath
+       continue
+       ;;
+
+      -R)
+       prev=xrpath
+       continue
+       ;;
+
+      -R*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         $echo "$modename: only absolute run-paths are allowed" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+       case "$xrpath " in
+       *" $dir "*) ;;
+       *) xrpath="$xrpath $dir" ;;
+       esac
+       continue
+       ;;
+
+      -static)
+       # The effects of -static are defined in a previous loop.
+       # We used to do the same as -all-static on platforms that
+       # didn't have a PIC flag, but the assumption that the effects
+       # would be equivalent was wrong.  It would break on at least
+       # Digital Unix and AIX.
+       continue
+       ;;
+
+      -thread-safe)
+       thread_safe=yes
+       continue
+       ;;
+
+      -version-info)
+       prev=vinfo
+       continue
+       ;;
+      -version-number)
+       prev=vinfo
+       vinfo_number=yes
+       continue
+       ;;
+
+      -Wc,*)
+       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+         case $flag in
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
+           flag="\"$flag\""
+           ;;
+         esac
+         arg="$arg $wl$flag"
+         compiler_flags="$compiler_flags $flag"
+       done
+       IFS="$save_ifs"
+       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+       ;;
+
+      -Wl,*)
+       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+         case $flag in
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
+           flag="\"$flag\""
+           ;;
+         esac
+         arg="$arg $wl$flag"
+         compiler_flags="$compiler_flags $wl$flag"
+         linker_flags="$linker_flags $flag"
+       done
+       IFS="$save_ifs"
+       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+       ;;
+
+      -Xcompiler)
+       prev=xcompiler
+       continue
+       ;;
+
+      -Xlinker)
+       prev=xlinker
+       continue
+       ;;
+
+      -XCClinker)
+       prev=xcclinker
+       continue
+       ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+
+      *.$objext)
+       # A standard object.
+       objs="$objs $arg"
+       ;;
+
+      *.lo)
+       # A libtool-controlled object.
+
+       # Check to see that this really is a libtool object.
+       if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         pic_object=
+         non_pic_object=
+
+         # Read the .lo file
+         # If there is no directory component, then add one.
+         case $arg in
+         */* | *\\*) . $arg ;;
+         *) . ./$arg ;;
+         esac
+
+         if test -z "$pic_object" || \
+            test -z "$non_pic_object" ||
+            test "$pic_object" = none && \
+            test "$non_pic_object" = none; then
+           $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         # Extract subdirectory from the argument.
+         xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$xdir" = "X$arg"; then
+           xdir=
+         else
+           xdir="$xdir/"
+         fi
+
+         if test "$pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           pic_object="$xdir$pic_object"
+
+           if test "$prev" = dlfiles; then
+             if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+               dlfiles="$dlfiles $pic_object"
+               prev=
+               continue
+             else
+               # If libtool objects are unsupported, then we need to preload.
+               prev=dlprefiles
+             fi
+           fi
+
+           # CHECK ME:  I think I busted this.  -Ossama
+           if test "$prev" = dlprefiles; then
+             # Preload the old-style object.
+             dlprefiles="$dlprefiles $pic_object"
+             prev=
+           fi
+
+           # A PIC object.
+           libobjs="$libobjs $pic_object"
+           arg="$pic_object"
+         fi
+
+         # Non-PIC object.
+         if test "$non_pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           non_pic_object="$xdir$non_pic_object"
+
+           # A standard non-PIC object
+           non_pic_objects="$non_pic_objects $non_pic_object"
+           if test -z "$pic_object" || test "$pic_object" = none ; then
+             arg="$non_pic_object"
+           fi
+         fi
+       else
+         # Only an error if not doing a dry-run.
+         if test -z "$run"; then
+           $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+           exit $EXIT_FAILURE
+         else
+           # Dry-run case.
+
+           # Extract subdirectory from the argument.
+           xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+           if test "X$xdir" = "X$arg"; then
+             xdir=
+           else
+             xdir="$xdir/"
+           fi
+
+           pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+           non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+           libobjs="$libobjs $pic_object"
+           non_pic_objects="$non_pic_objects $non_pic_object"
+         fi
+       fi
+       ;;
+
+      *.$libext)
+       # An archive.
+       deplibs="$deplibs $arg"
+       old_deplibs="$old_deplibs $arg"
+       continue
+       ;;
+
+      *.la)
+       # A libtool-controlled library.
+
+       if test "$prev" = dlfiles; then
+         # This library was specified with -dlopen.
+         dlfiles="$dlfiles $arg"
+         prev=
+       elif test "$prev" = dlprefiles; then
+         # The library was specified with -dlpreopen.
+         dlprefiles="$dlprefiles $arg"
+         prev=
+       else
+         deplibs="$deplibs $arg"
+       fi
+       continue
+       ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d "$output_objdir"; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      status=$?
+      if test "$status" -ne 0 && test ! -d "$output_objdir"; then
+       exit $status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    case $host in
+    *cygwin* | *mingw* | *pw32*)
+      # don't eliminate duplications in $postdeps and $predeps
+      duplicate_compiler_generated_deps=yes
+      ;;
+    *)
+      duplicate_compiler_generated_deps=$duplicate_deps
+      ;;
+    esac
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if test "X$duplicate_deps" = "Xyes" ; then
+       case "$libs " in
+       *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+       esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+       for pre_post_dep in $predeps $postdeps; do
+         case "$pre_post_deps " in
+         *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+         esac
+         pre_post_deps="$pre_post_deps $pre_post_dep"
+       done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+    case $linkmode in
+    lib)
+       passes="conv link"
+       for file in $dlfiles $dlprefiles; do
+         case $file in
+         *.la) ;;
+         *)
+           $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+           exit $EXIT_FAILURE
+           ;;
+         esac
+       done
+       ;;
+    prog)
+       compile_deplibs=
+       finalize_deplibs=
+       alldeplibs=no
+       newdlfiles=
+       newdlprefiles=
+       passes="conv scan dlopen dlpreopen link"
+       ;;
+    *)  passes="conv"
+       ;;
+    esac
+    for pass in $passes; do
+      if test "$linkmode,$pass" = "lib,link" ||
+        test "$linkmode,$pass" = "prog,scan"; then
+       libs="$deplibs"
+       deplibs=
+      fi
+      if test "$linkmode" = prog; then
+       case $pass in
+       dlopen) libs="$dlfiles" ;;
+       dlpreopen) libs="$dlprefiles" ;;
+       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+       esac
+      fi
+      if test "$pass" = dlopen; then
+       # Collect dlpreopened libraries
+       save_deplibs="$deplibs"
+       deplibs=
+      fi
+      for deplib in $libs; do
+       lib=
+       found=no
+       case $deplib in
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+         if test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$deplib $compile_deplibs"
+           finalize_deplibs="$deplib $finalize_deplibs"
+         else
+           deplibs="$deplib $deplibs"
+         fi
+         continue
+         ;;
+       -l*)
+         if test "$linkmode" != lib && test "$linkmode" != prog; then
+           $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+           continue
+         fi
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+           continue
+         fi
+         name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+         for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+           for search_ext in .la $std_shrext .so .a; do
+             # Search the libtool library
+             lib="$searchdir/lib${name}${search_ext}"
+             if test -f "$lib"; then
+               if test "$search_ext" = ".la"; then
+                 found=yes
+               else
+                 found=no
+               fi
+               break 2
+             fi
+           done
+         done
+         if test "$found" != yes; then
+           # deplib doesn't seem to be a libtool library
+           if test "$linkmode,$pass" = "prog,link"; then
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             deplibs="$deplib $deplibs"
+             test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+           fi
+           continue
+         else # deplib is a libtool library
+           # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+           # We need to do some special things here, and not later.
+           if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+             case " $predeps $postdeps " in
+             *" $deplib "*)
+               if (${SED} -e '2q' $lib |
+                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+                 library_names=
+                 old_library=
+                 case $lib in
+                 */* | *\\*) . $lib ;;
+                 *) . ./$lib ;;
+                 esac
+                 for l in $old_library $library_names; do
+                   ll="$l"
+                 done
+                 if test "X$ll" = "X$old_library" ; then # only static version available
+                   found=no
+                   ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+                   test "X$ladir" = "X$lib" && ladir="."
+                   lib=$ladir/$old_library
+                   if test "$linkmode,$pass" = "prog,link"; then
+                     compile_deplibs="$deplib $compile_deplibs"
+                     finalize_deplibs="$deplib $finalize_deplibs"
+                   else
+                     deplibs="$deplib $deplibs"
+                     test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+                   fi
+                   continue
+                 fi
+               fi
+               ;;
+             *) ;;
+             esac
+           fi
+         fi
+         ;; # -l
+       -L*)
+         case $linkmode in
+         lib)
+           deplibs="$deplib $deplibs"
+           test "$pass" = conv && continue
+           newdependency_libs="$deplib $newdependency_libs"
+           newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+           ;;
+         prog)
+           if test "$pass" = conv; then
+             deplibs="$deplib $deplibs"
+             continue
+           fi
+           if test "$pass" = scan; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+           ;;
+         *)
+           $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+           ;;
+         esac # linkmode
+         continue
+         ;; # -L
+       -R*)
+         if test "$pass" = link; then
+           dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+           # Make sure the xrpath contains only unique directories.
+           case "$xrpath " in
+           *" $dir "*) ;;
+           *) xrpath="$xrpath $dir" ;;
+           esac
+         fi
+         deplibs="$deplib $deplibs"
+         continue
+         ;;
+       *.la) lib="$deplib" ;;
+       *.$libext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+           continue
+         fi
+         case $linkmode in
+         lib)
+           if test "$deplibs_check_method" != pass_all; then
+             $echo
+             $echo "*** Warning: Trying to link with static lib archive $deplib."
+             $echo "*** I have the capability to make that library automatically link in when"
+             $echo "*** you link to this library.  But I can only do this if you have a"
+             $echo "*** shared version of the library, which you do not appear to have"
+             $echo "*** because the file extensions .$libext of this argument makes me believe"
+             $echo "*** that it is just a static archive that I should not used here."
+           else
+             $echo
+             $echo "*** Warning: Linking the shared library $output against the"
+             $echo "*** static library $deplib is not portable!"
+             deplibs="$deplib $deplibs"
+           fi
+           continue
+           ;;
+         prog)
+           if test "$pass" != link; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           continue
+           ;;
+         esac # linkmode
+         ;; # *.$libext
+       *.lo | *.$objext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+         elif test "$linkmode" = prog; then
+           if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+             # If there is no dlopen support or we're linking statically,
+             # we need to preload.
+             newdlprefiles="$newdlprefiles $deplib"
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             newdlfiles="$newdlfiles $deplib"
+           fi
+         fi
+         continue
+         ;;
+       %DEPLIBS%)
+         alldeplibs=yes
+         continue
+         ;;
+       esac # case $deplib
+       if test "$found" = yes || test -f "$lib"; then :
+       else
+         $echo "$modename: cannot find the library \`$lib'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$ladir" = "X$lib" && ladir="."
+
+       dlname=
+       dlopen=
+       dlpreopen=
+       libdir=
+       library_names=
+       old_library=
+       # If the library was installed with an old release of libtool,
+       # it will not redefine variables installed, or shouldnotlink
+       installed=yes
+       shouldnotlink=no
+
+       # Read the .la file
+       case $lib in
+       */* | *\\*) . $lib ;;
+       *) . ./$lib ;;
+       esac
+
+       if test "$linkmode,$pass" = "lib,link" ||
+          test "$linkmode,$pass" = "prog,scan" ||
+          { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+         test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+         test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+       fi
+
+       if test "$pass" = conv; then
+         # Only check for convenience libraries
+         deplibs="$lib $deplibs"
+         if test -z "$libdir"; then
+           if test -z "$old_library"; then
+             $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+             exit $EXIT_FAILURE
+           fi
+           # It is a libtool convenience library, so add in its objects.
+           convenience="$convenience $ladir/$objdir/$old_library"
+           old_convenience="$old_convenience $ladir/$objdir/$old_library"
+           tmp_libs=
+           for deplib in $dependency_libs; do
+             deplibs="$deplib $deplibs"
+              if test "X$duplicate_deps" = "Xyes" ; then
+               case "$tmp_libs " in
+               *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+               esac
+              fi
+             tmp_libs="$tmp_libs $deplib"
+           done
+         elif test "$linkmode" != prog && test "$linkmode" != lib; then
+           $echo "$modename: \`$lib' is not a convenience library" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         continue
+       fi # $pass = conv
+
+
+       # Get the name of the library we link against.
+       linklib=
+       for l in $old_library $library_names; do
+         linklib="$l"
+       done
+       if test -z "$linklib"; then
+         $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # This library was specified with -dlopen.
+       if test "$pass" = dlopen; then
+         if test -z "$libdir"; then
+           $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         if test -z "$dlname" ||
+            test "$dlopen_support" != yes ||
+            test "$build_libtool_libs" = no; then
+           # If there is no dlname, no dlopen support or we're linking
+           # statically, we need to preload.  We also need to preload any
+           # dependent libraries so libltdl's deplib preloader doesn't
+           # bomb out in the load deplibs phase.
+           dlprefiles="$dlprefiles $lib $dependency_libs"
+         else
+           newdlfiles="$newdlfiles $lib"
+         fi
+         continue
+       fi # $pass = dlopen
+
+       # We need an absolute path.
+       case $ladir in
+       [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+       *)
+         abs_ladir=`cd "$ladir" && pwd`
+         if test -z "$abs_ladir"; then
+           $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+           $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+           abs_ladir="$ladir"
+         fi
+         ;;
+       esac
+       laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+       # Find the relevant object directory and library name.
+       if test "X$installed" = Xyes; then
+         if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+           $echo "$modename: warning: library \`$lib' was moved." 1>&2
+           dir="$ladir"
+           absdir="$abs_ladir"
+           libdir="$abs_ladir"
+         else
+           dir="$libdir"
+           absdir="$libdir"
+         fi
+       else
+         dir="$ladir/$objdir"
+         absdir="$abs_ladir/$objdir"
+         # Remove this search path later
+         notinst_path="$notinst_path $abs_ladir"
+       fi # $installed = yes
+       name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+       # This library was specified with -dlpreopen.
+       if test "$pass" = dlpreopen; then
+         if test -z "$libdir"; then
+           $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         # Prefer using a static library (so that no silly _DYNAMIC symbols
+         # are required to link).
+         if test -n "$old_library"; then
+           newdlprefiles="$newdlprefiles $dir/$old_library"
+         # Otherwise, use the dlname, so that lt_dlopen finds it.
+         elif test -n "$dlname"; then
+           newdlprefiles="$newdlprefiles $dir/$dlname"
+         else
+           newdlprefiles="$newdlprefiles $dir/$linklib"
+         fi
+       fi # $pass = dlpreopen
+
+       if test -z "$libdir"; then
+         # Link the convenience library
+         if test "$linkmode" = lib; then
+           deplibs="$dir/$old_library $deplibs"
+         elif test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$dir/$old_library $compile_deplibs"
+           finalize_deplibs="$dir/$old_library $finalize_deplibs"
+         else
+           deplibs="$lib $deplibs" # used for prog,scan pass
+         fi
+         continue
+       fi
+
+
+       if test "$linkmode" = prog && test "$pass" != link; then
+         newlib_search_path="$newlib_search_path $ladir"
+         deplibs="$lib $deplibs"
+
+         linkalldeplibs=no
+         if test "$link_all_deplibs" != no || test -z "$library_names" ||
+            test "$build_libtool_libs" = no; then
+           linkalldeplibs=yes
+         fi
+
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           case $deplib in
+           -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+           esac
+           # Need to link against all dependency_libs?
+           if test "$linkalldeplibs" = yes; then
+             deplibs="$deplib $deplibs"
+           else
+             # Need to hardcode shared library paths
+             # or/and link against static libraries
+             newdependency_libs="$deplib $newdependency_libs"
+           fi
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
+           tmp_libs="$tmp_libs $deplib"
+         done # for deplib
+         continue
+       fi # $linkmode = prog...
+
+       if test "$linkmode,$pass" = "prog,link"; then
+         if test -n "$library_names" &&
+            { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+           # We need to hardcode the library path
+           if test -n "$shlibpath_var"; then
+             # Make sure the rpath contains only unique directories.
+             case "$temp_rpath " in
+             *" $dir "*) ;;
+             *" $absdir "*) ;;
+             *) temp_rpath="$temp_rpath $dir" ;;
+             esac
+           fi
+
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) compile_rpath="$compile_rpath $absdir"
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) finalize_rpath="$finalize_rpath $libdir"
+             esac
+             ;;
+           esac
+         fi # $linkmode,$pass = prog,link...
+
+         if test "$alldeplibs" = yes &&
+            { test "$deplibs_check_method" = pass_all ||
+              { test "$build_libtool_libs" = yes &&
+                test -n "$library_names"; }; }; then
+           # We only need to search for static libraries
+           continue
+         fi
+       fi
+
+       link_static=no # Whether the deplib will be linked statically
+       if test -n "$library_names" &&
+          { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+         if test "$installed" = no; then
+           notinst_deplibs="$notinst_deplibs $lib"
+           need_relink=yes
+         fi
+         # This is a shared library
+
+         # Warn about portability, can't link against -module's on
+         # some systems (darwin)
+         if test "$shouldnotlink" = yes && test "$pass" = link ; then
+           $echo
+           if test "$linkmode" = prog; then
+             $echo "*** Warning: Linking the executable $output against the loadable module"
+           else
+             $echo "*** Warning: Linking the shared library $output against the loadable module"
+           fi
+           $echo "*** $linklib is not portable!"
+         fi
+         if test "$linkmode" = lib &&
+            test "$hardcode_into_libs" = yes; then
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) compile_rpath="$compile_rpath $absdir"
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) finalize_rpath="$finalize_rpath $libdir"
+             esac
+             ;;
+           esac
+         fi
+
+         if test -n "$old_archive_from_expsyms_cmds"; then
+           # figure out the soname
+           set dummy $library_names
+           realname="$2"
+           shift; shift
+           libname=`eval \\$echo \"$libname_spec\"`
+           # use dlname if we got it. it's perfectly good, no?
+           if test -n "$dlname"; then
+             soname="$dlname"
+           elif test -n "$soname_spec"; then
+             # bleh windows
+             case $host in
+             *cygwin* | mingw*)
+               major=`expr $current - $age`
+               versuffix="-$major"
+               ;;
+             esac
+             eval soname=\"$soname_spec\"
+           else
+             soname="$realname"
+           fi
+
+           # Make a new name for the extract_expsyms_cmds to use
+           soroot="$soname"
+           soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+           newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+           # If the library has no export list, then create one now
+           if test -f "$output_objdir/$soname-def"; then :
+           else
+             $show "extracting exported symbol list from \`$soname'"
+             save_ifs="$IFS"; IFS='~'
+             cmds=$extract_expsyms_cmds
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+             done
+             IFS="$save_ifs"
+           fi
+
+           # Create $newlib
+           if test -f "$output_objdir/$newlib"; then :; else
+             $show "generating import library for \`$soname'"
+             save_ifs="$IFS"; IFS='~'
+             cmds=$old_archive_from_expsyms_cmds
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+             done
+             IFS="$save_ifs"
+           fi
+           # make sure the library variables are pointing to the new library
+           dir=$output_objdir
+           linklib=$newlib
+         fi # test -n "$old_archive_from_expsyms_cmds"
+
+         if test "$linkmode" = prog || test "$mode" != relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           lib_linked=yes
+           case $hardcode_action in
+           immediate | unsupported)
+             if test "$hardcode_direct" = no; then
+               add="$dir/$linklib"
+               case $host in
+                 *-*-sco3.2v5* ) add_dir="-L$dir" ;;
+                 *-*-darwin* )
+                   # if the lib is a module then we can not link against
+                   # it, someone is ignoring the new warnings I added
+                   if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then
+                     $echo "** Warning, lib $linklib is a module, not a shared library"
+                     if test -z "$old_library" ; then
+                       $echo
+                       $echo "** And there doesn't seem to be a static archive available"
+                       $echo "** The link will probably fail, sorry"
+                     else
+                       add="$dir/$old_library"
+                     fi
+                   fi
+               esac
+             elif test "$hardcode_minus_L" = no; then
+               case $host in
+               *-*-sunos*) add_shlibpath="$dir" ;;
+               esac
+               add_dir="-L$dir"
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = no; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           relink)
+             if test "$hardcode_direct" = yes; then
+               add="$dir/$linklib"
+             elif test "$hardcode_minus_L" = yes; then
+               add_dir="-L$dir"
+               # Try looking first in the location we're being installed to.
+               if test -n "$inst_prefix_dir"; then
+                 case "$libdir" in
+                   [\\/]*)
+                     add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                     ;;
+                 esac
+               fi
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = yes; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           *) lib_linked=no ;;
+           esac
+
+           if test "$lib_linked" != yes; then
+             $echo "$modename: configuration error: unsupported hardcode properties"
+             exit $EXIT_FAILURE
+           fi
+
+           if test -n "$add_shlibpath"; then
+             case :$compile_shlibpath: in
+             *":$add_shlibpath:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+             esac
+           fi
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+             test -n "$add" && compile_deplibs="$add $compile_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+             if test "$hardcode_direct" != yes && \
+                test "$hardcode_minus_L" != yes && \
+                test "$hardcode_shlibpath_var" = yes; then
+               case :$finalize_shlibpath: in
+               *":$libdir:"*) ;;
+               *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+               esac
+             fi
+           fi
+         fi
+
+         if test "$linkmode" = prog || test "$mode" = relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           # Finalize command for both is simple: just hardcode it.
+           if test "$hardcode_direct" = yes; then
+             add="$libdir/$linklib"
+           elif test "$hardcode_minus_L" = yes; then
+             add_dir="-L$libdir"
+             add="-l$name"
+           elif test "$hardcode_shlibpath_var" = yes; then
+             case :$finalize_shlibpath: in
+             *":$libdir:"*) ;;
+             *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+             esac
+             add="-l$name"
+           elif test "$hardcode_automatic" = yes; then
+             if test -n "$inst_prefix_dir" &&
+                test -f "$inst_prefix_dir$libdir/$linklib" ; then
+               add="$inst_prefix_dir$libdir/$linklib"
+             else
+               add="$libdir/$linklib"
+             fi
+           else
+             # We cannot seem to hardcode it, guess we'll fake it.
+             add_dir="-L$libdir"
+             # Try looking first in the location we're being installed to.
+             if test -n "$inst_prefix_dir"; then
+               case "$libdir" in
+                 [\\/]*)
+                   add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                   ;;
+               esac
+             fi
+             add="-l$name"
+           fi
+
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+             test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+           fi
+         fi
+       elif test "$linkmode" = prog; then
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_deplibs="$dir/$linklib $compile_deplibs"
+           finalize_deplibs="$dir/$linklib $finalize_deplibs"
+         else
+           compile_deplibs="-l$name -L$dir $compile_deplibs"
+           finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+         fi
+       elif test "$build_libtool_libs" = yes; then
+         # Not a shared library
+         if test "$deplibs_check_method" != pass_all; then
+           # We're trying link a shared library against a static one
+           # but the system doesn't support it.
+
+           # Just print a warning and add the library to dependency_libs so
+           # that the program can be linked against the static library.
+           $echo
+           $echo "*** Warning: This system can not link to static lib archive $lib."
+           $echo "*** I have the capability to make that library automatically link in when"
+           $echo "*** you link to this library.  But I can only do this if you have a"
+           $echo "*** shared version of the library, which you do not appear to have."
+           if test "$module" = yes; then
+             $echo "*** But as you try to build a module library, libtool will still create "
+             $echo "*** a static module, that should work as long as the dlopening application"
+             $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+             if test -z "$global_symbol_pipe"; then
+               $echo
+               $echo "*** However, this would only work if libtool was able to extract symbol"
+               $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+               $echo "*** not find such a program.  So, this module is probably useless."
+               $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+             fi
+             if test "$build_old_libs" = no; then
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         else
+           convenience="$convenience $dir/$old_library"
+           old_convenience="$old_convenience $dir/$old_library"
+           deplibs="$dir/$old_library $deplibs"
+           link_static=yes
+         fi
+       fi # link shared/static library?
+
+       if test "$linkmode" = lib; then
+         if test -n "$dependency_libs" &&
+            { test "$hardcode_into_libs" != yes ||
+              test "$build_old_libs" = yes ||
+              test "$link_static" = yes; }; then
+           # Extract -R from dependency_libs
+           temp_deplibs=
+           for libdir in $dependency_libs; do
+             case $libdir in
+             -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+                  case " $xrpath " in
+                  *" $temp_xrpath "*) ;;
+                  *) xrpath="$xrpath $temp_xrpath";;
+                  esac;;
+             *) temp_deplibs="$temp_deplibs $libdir";;
+             esac
+           done
+           dependency_libs="$temp_deplibs"
+         fi
+
+         newlib_search_path="$newlib_search_path $absdir"
+         # Link against this library
+         test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+         # ... and its dependency_libs
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           newdependency_libs="$deplib $newdependency_libs"
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
+           tmp_libs="$tmp_libs $deplib"
+         done
+
+         if test "$link_all_deplibs" != no; then
+           # Add the search paths of all dependency libraries
+           for deplib in $dependency_libs; do
+             case $deplib in
+             -L*) path="$deplib" ;;
+             *.la)
+               dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+               test "X$dir" = "X$deplib" && dir="."
+               # We need an absolute path.
+               case $dir in
+               [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+               *)
+                 absdir=`cd "$dir" && pwd`
+                 if test -z "$absdir"; then
+                   $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+                   absdir="$dir"
+                 fi
+                 ;;
+               esac
+               if grep "^installed=no" $deplib > /dev/null; then
+                 path="$absdir/$objdir"
+               else
+                 eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+                 if test -z "$libdir"; then
+                   $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+                   exit $EXIT_FAILURE
+                 fi
+                 if test "$absdir" != "$libdir"; then
+                   $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+                 fi
+                 path="$absdir"
+               fi
+               depdepl=
+               case $host in
+               *-*-darwin*)
+                 # we do not want to link against static libs,
+                 # but need to link against shared
+                 eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+                 if test -n "$deplibrary_names" ; then
+                   for tmp in $deplibrary_names ; do
+                     depdepl=$tmp
+                   done
+                   if test -f "$path/$depdepl" ; then
+                     depdepl="$path/$depdepl"
+                   fi
+                   # do not add paths which are already there
+                   case " $newlib_search_path " in
+                   *" $path "*) ;;
+                   *) newlib_search_path="$newlib_search_path $path";;
+                   esac
+                 fi
+                 path=""
+                 ;;
+               *)
+                 path="-L$path"
+                 ;;
+               esac
+               ;;
+             -l*)
+               case $host in
+               *-*-darwin*)
+                 # Again, we only want to link against shared libraries
+                 eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+                 for tmp in $newlib_search_path ; do
+                   if test -f "$tmp/lib$tmp_libs.dylib" ; then
+                     eval depdepl="$tmp/lib$tmp_libs.dylib"
+                     break
+                   fi
+                 done
+                 path=""
+                 ;;
+               *) continue ;;
+               esac
+               ;;
+             *) continue ;;
+             esac
+             case " $deplibs " in
+             *" $depdepl "*) ;;
+             *) deplibs="$depdepl $deplibs" ;;
+             esac
+             case " $deplibs " in
+             *" $path "*) ;;
+             *) deplibs="$deplibs $path" ;;
+             esac
+           done
+         fi # link_all_deplibs != no
+       fi # linkmode = lib
+      done # for deplib in $libs
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+       # Link the dlpreopened libraries before other libraries
+       for deplib in $save_deplibs; do
+         deplibs="$deplib $deplibs"
+       done
+      fi
+      if test "$pass" != dlopen; then
+       if test "$pass" != conv; then
+         # Make sure lib_search_path contains only unique directories.
+         lib_search_path=
+         for dir in $newlib_search_path; do
+           case "$lib_search_path " in
+           *" $dir "*) ;;
+           *) lib_search_path="$lib_search_path $dir" ;;
+           esac
+         done
+         newlib_search_path=
+       fi
+
+       if test "$linkmode,$pass" != "prog,link"; then
+         vars="deplibs"
+       else
+         vars="compile_deplibs finalize_deplibs"
+       fi
+       for var in $vars dependency_libs; do
+         # Add libraries to $var in reverse order
+         eval tmp_libs=\"\$$var\"
+         new_libs=
+         for deplib in $tmp_libs; do
+           # FIXME: Pedantically, this is the right thing to do, so
+           #        that some nasty dependency loop isn't accidentally
+           #        broken:
+           #new_libs="$deplib $new_libs"
+           # Pragmatically, this seems to cause very few problems in
+           # practice:
+           case $deplib in
+           -L*) new_libs="$deplib $new_libs" ;;
+           -R*) ;;
+           *)
+             # And here is the reason: when a library appears more
+             # than once as an explicit dependence of a library, or
+             # is implicitly linked in more than once by the
+             # compiler, it is considered special, and multiple
+             # occurrences thereof are not removed.  Compare this
+             # with having the same library being listed as a
+             # dependency of multiple other libraries: in this case,
+             # we know (pedantically, we assume) the library does not
+             # need to be listed more than once, so we keep only the
+             # last copy.  This is not always right, but it is rare
+             # enough that we require users that really mean to play
+             # such unportable linking tricks to link the library
+             # using -Wl,-lname, so that libtool does not consider it
+             # for duplicate removal.
+             case " $specialdeplibs " in
+             *" $deplib "*) new_libs="$deplib $new_libs" ;;
+             *)
+               case " $new_libs " in
+               *" $deplib "*) ;;
+               *) new_libs="$deplib $new_libs" ;;
+               esac
+               ;;
+             esac
+             ;;
+           esac
+         done
+         tmp_libs=
+         for deplib in $new_libs; do
+           case $deplib in
+           -L*)
+             case " $tmp_libs " in
+             *" $deplib "*) ;;
+             *) tmp_libs="$tmp_libs $deplib" ;;
+             esac
+             ;;
+           *) tmp_libs="$tmp_libs $deplib" ;;
+           esac
+         done
+         eval $var=\"$tmp_libs\"
+       done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+       case " $predeps $postdeps $compiler_lib_search_path " in
+       *" $i "*)
+         i=""
+         ;;
+       esac
+       if test -n "$i" ; then
+         tmp_libs="$tmp_libs $i"
+       fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+       $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+       name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+       eval shared_ext=\"$shrext_cmds\"
+       eval libname=\"$libname_spec\"
+       ;;
+      *)
+       if test "$module" = no; then
+         $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       if test "$need_lib_prefix" != no; then
+         # Add the "lib" prefix for modules if required
+         name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+         eval shared_ext=\"$shrext_cmds\"
+         eval libname=\"$libname_spec\"
+       else
+         libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+       fi
+       ;;
+      esac
+
+      if test -n "$objs"; then
+       if test "$deplibs_check_method" != pass_all; then
+         $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+         exit $EXIT_FAILURE
+       else
+         $echo
+         $echo "*** Warning: Linking the shared library $output against the non-libtool"
+         $echo "*** objects $objs is not portable!"
+         libobjs="$libobjs $objs"
+       fi
+      fi
+
+      if test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test "$#" -gt 2; then
+       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+       if test "$build_libtool_libs" = yes; then
+         # Building a libtool convenience library.
+         # Some compilers have problems with a `.al' extension so
+         # convenience libraries should have the same extension an
+         # archive normally would.
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
+         build_libtool_libs=convenience
+         build_old_libs=yes
+       fi
+
+       if test -n "$vinfo"; then
+         $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
+       fi
+
+       if test -n "$release"; then
+         $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+       fi
+      else
+
+       # Parse the version information argument.
+       save_ifs="$IFS"; IFS=':'
+       set dummy $vinfo 0 0 0
+       IFS="$save_ifs"
+
+       if test -n "$8"; then
+         $echo "$modename: too many parameters to \`-version-info'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # convert absolute version numbers to libtool ages
+       # this retains compatibility with .la files and attempts
+       # to make the code below a bit more comprehensible
+
+       case $vinfo_number in
+       yes)
+         number_major="$2"
+         number_minor="$3"
+         number_revision="$4"
+         #
+         # There are really only two kinds -- those that
+         # use the current revision as the major version
+         # and those that subtract age and use age as
+         # a minor version.  But, then there is irix
+         # which has an extra 1 added just for fun
+         #
+         case $version_type in
+         darwin|linux|osf|windows)
+           current=`expr $number_major + $number_minor`
+           age="$number_minor"
+           revision="$number_revision"
+           ;;
+         freebsd-aout|freebsd-elf|sunos)
+           current="$number_major"
+           revision="$number_minor"
+           age="0"
+           ;;
+         irix|nonstopux)
+           current=`expr $number_major + $number_minor - 1`
+           age="$number_minor"
+           revision="$number_minor"
+           ;;
+         esac
+         ;;
+       no)
+         current="$2"
+         revision="$3"
+         age="$4"
+         ;;
+       esac
+
+       # Check that each of the things are valid numbers.
+       case $current in
+       0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       case $revision in
+       0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       case $age in
+       0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       if test "$age" -gt "$current"; then
+         $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Calculate the version variables.
+       major=
+       versuffix=
+       verstring=
+       case $version_type in
+       none) ;;
+
+       darwin)
+         # Like Linux, but with the current version available in
+         # verstring for coding it into the library header
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         # Darwin ld doesn't like 0 for these options...
+         minor_current=`expr $current + 1`
+         verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+         ;;
+
+       freebsd-aout)
+         major=".$current"
+         versuffix=".$current.$revision";
+         ;;
+
+       freebsd-elf)
+         major=".$current"
+         versuffix=".$current";
+         ;;
+
+       irix | nonstopux)
+         major=`expr $current - $age + 1`
+
+         case $version_type in
+           nonstopux) verstring_prefix=nonstopux ;;
+           *)         verstring_prefix=sgi ;;
+         esac
+         verstring="$verstring_prefix$major.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$revision
+         while test "$loop" -ne 0; do
+           iface=`expr $revision - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring_prefix$major.$iface:$verstring"
+         done
+
+         # Before this point, $major must not contain `.'.
+         major=.$major
+         versuffix="$major.$revision"
+         ;;
+
+       linux)
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         ;;
+
+       osf)
+         major=.`expr $current - $age`
+         versuffix=".$current.$age.$revision"
+         verstring="$current.$age.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$age
+         while test "$loop" -ne 0; do
+           iface=`expr $current - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring:${iface}.0"
+         done
+
+         # Make executables depend on our current version.
+         verstring="$verstring:${current}.0"
+         ;;
+
+       sunos)
+         major=".$current"
+         versuffix=".$current.$revision"
+         ;;
+
+       windows)
+         # Use '-' rather than '.', since we only want one
+         # extension on DOS 8.3 filesystems.
+         major=`expr $current - $age`
+         versuffix="-$major"
+         ;;
+
+       *)
+         $echo "$modename: unknown library version type \`$version_type'" 1>&2
+         $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       # Clear the version info if we defaulted, and they specified a release.
+       if test -z "$vinfo" && test -n "$release"; then
+         major=
+         case $version_type in
+         darwin)
+           # we can't check for "0.0" in archive_cmds due to quoting
+           # problems, so we reset it completely
+           verstring=
+           ;;
+         *)
+           verstring="0.0"
+           ;;
+         esac
+         if test "$need_version" = no; then
+           versuffix=
+         else
+           versuffix=".0.0"
+         fi
+       fi
+
+       # Remove version info from name if versioning should be avoided
+       if test "$avoid_version" = yes && test "$need_version" = no; then
+         major=
+         versuffix=
+         verstring=""
+       fi
+
+       # Check to see if the archive will have undefined symbols.
+       if test "$allow_undefined" = yes; then
+         if test "$allow_undefined_flag" = unsupported; then
+           $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+           build_libtool_libs=no
+           build_old_libs=yes
+         fi
+       else
+         # Don't allow undefined symbols.
+         allow_undefined_flag="$no_undefined_flag"
+       fi
+      fi
+
+      if test "$mode" != relink; then
+       # Remove our outputs, but don't remove object files since they
+       # may have been created when compiling PIC objects.
+       removelist=
+       tempremovelist=`$echo "$output_objdir/*"`
+       for p in $tempremovelist; do
+         case $p in
+           *.$objext)
+              ;;
+           $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+              if test "X$precious_files_regex" != "X"; then
+                if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+                then
+                  continue
+                fi
+              fi
+              removelist="$removelist $p"
+              ;;
+           *) ;;
+         esac
+       done
+       if test -n "$removelist"; then
+         $show "${rm}r $removelist"
+         $run ${rm}r $removelist
+       fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+       oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+       # Transform .lo files to .o files.
+       oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      for path in $notinst_path; do
+       lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'`
+       deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'`
+       dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'`
+      done
+
+      if test -n "$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       temp_xrpath=
+       for libdir in $xrpath; do
+         temp_xrpath="$temp_xrpath -R$libdir"
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+       if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+         dependency_libs="$temp_xrpath $dependency_libs"
+       fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+       case " $dlprefiles $dlfiles " in
+       *" $lib "*) ;;
+       *) dlfiles="$dlfiles $lib" ;;
+       esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+       case "$dlprefiles " in
+       *" $lib "*) ;;
+       *) dlprefiles="$dlprefiles $lib" ;;
+       esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+       if test -n "$rpath"; then
+         case $host in
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+           # these systems don't actually have a c library (as such)!
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C library is in the System framework
+           deplibs="$deplibs -framework System"
+           ;;
+         *-*-netbsd*)
+           # Don't link with libc until the a.out ld.so is fixed.
+           ;;
+         *-*-openbsd* | *-*-freebsd*)
+           # Do not include libc due to us having libc/libc_r.
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *)
+           # Add libc to deplibs on all other systems if necessary.
+           if test "$build_libtool_need_lc" = "yes"; then
+             deplibs="$deplibs -lc"
+           fi
+           ;;
+         esac
+       fi
+
+       # Transform deplibs into only deplibs that can be linked in shared.
+       name_save=$name
+       libname_save=$libname
+       release_save=$release
+       versuffix_save=$versuffix
+       major_save=$major
+       # I'm not sure if I'm treating the release correctly.  I think
+       # release should show up in the -l (ie -lgmp5) so we don't want to
+       # add it in twice.  Is that correct?
+       release=""
+       versuffix=""
+       major=""
+       newdeplibs=
+       droppeddeps=no
+       case $deplibs_check_method in
+       pass_all)
+         # Don't check for shared/static.  Everything works.
+         # This might be a little naive.  We might want to check
+         # whether the library exists or not.  But this is on
+         # osf3 & osf4 and I'm not really sure... Just
+         # implementing what was already the behavior.
+         newdeplibs=$deplibs
+         ;;
+       test_compile)
+         # This code stresses the "libraries are programs" paradigm to its
+         # limits. Maybe even breaks it.  We compile a program, linking it
+         # against the deplibs as a proxy for the library.  Then we can check
+         # whether they linked in statically or dynamically with ldd.
+         $rm conftest.c
+         cat > conftest.c <<EOF
+         int main() { return 0; }
+EOF
+         $rm conftest
+         $LTCC -o conftest conftest.c $deplibs
+         if test "$?" -eq 0 ; then
+           ldd_output=`ldd conftest`
+           for i in $deplibs; do
+             name="`expr $i : '-l\(.*\)'`"
+             # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" -ne "0"; then
+               if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                 case " $predeps $postdeps " in
+                 *" $i "*)
+                   newdeplibs="$newdeplibs $i"
+                   i=""
+                   ;;
+                 esac
+               fi
+               if test -n "$i" ; then
+                 libname=`eval \\$echo \"$libname_spec\"`
+                 deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                 set dummy $deplib_matches
+                 deplib_match=$2
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                   newdeplibs="$newdeplibs $i"
+                 else
+                   droppeddeps=yes
+                   $echo
+                   $echo "*** Warning: dynamic linker does not accept needed library $i."
+                   $echo "*** I have the capability to make that library automatically link in when"
+                   $echo "*** you link to this library.  But I can only do this if you have a"
+                   $echo "*** shared version of the library, which I believe you do not have"
+                   $echo "*** because a test_compile did reveal that the linker did not use it for"
+                   $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+                 fi
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         else
+           # Error occurred in the first compile.  Let's try to salvage
+           # the situation: Compile a separate program for each library.
+           for i in $deplibs; do
+             name="`expr $i : '-l\(.*\)'`"
+             # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" != "0"; then
+               $rm conftest
+               $LTCC -o conftest conftest.c $i
+               # Did it work?
+               if test "$?" -eq 0 ; then
+                 ldd_output=`ldd conftest`
+                 if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                   case " $predeps $postdeps " in
+                   *" $i "*)
+                     newdeplibs="$newdeplibs $i"
+                     i=""
+                     ;;
+                   esac
+                 fi
+                 if test -n "$i" ; then
+                   libname=`eval \\$echo \"$libname_spec\"`
+                   deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                   set dummy $deplib_matches
+                   deplib_match=$2
+                   if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                     newdeplibs="$newdeplibs $i"
+                   else
+                     droppeddeps=yes
+                     $echo
+                     $echo "*** Warning: dynamic linker does not accept needed library $i."
+                     $echo "*** I have the capability to make that library automatically link in when"
+                     $echo "*** you link to this library.  But I can only do this if you have a"
+                     $echo "*** shared version of the library, which you do not appear to have"
+                     $echo "*** because a test_compile did reveal that the linker did not use this one"
+                     $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+                   fi
+                 fi
+               else
+                 droppeddeps=yes
+                 $echo
+                 $echo "*** Warning!  Library $i is needed by this library but I was not able to"
+                 $echo "***  make it link in!  You will probably need to install it or some"
+                 $echo "*** library that it depends on before this library will be fully"
+                 $echo "*** functional.  Installing it before continuing would be even better."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         fi
+         ;;
+       file_magic*)
+         set dummy $deplibs_check_method
+         file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+         for a_deplib in $deplibs; do
+           name="`expr $a_deplib : '-l\(.*\)'`"
+           # If $name is empty we are operating on a -L argument.
+            if test "$name" != "" && test  "$name" != "0"; then
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 newdeplibs="$newdeplibs $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 for potent_lib in $potential_libs; do
+                     # Follow soft links.
+                     if ls -lLd "$potent_lib" 2>/dev/null \
+                        | grep " -> " >/dev/null; then
+                       continue
+                     fi
+                     # The statement above tries to avoid entering an
+                     # endless loop below, in case of cyclic links.
+                     # We might still enter an endless loop, since a link
+                     # loop can be closed while we follow links,
+                     # but so what?
+                     potlib="$potent_lib"
+                     while test -h "$potlib" 2>/dev/null; do
+                       potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+                       case $potliblink in
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+                       *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+                       esac
+                     done
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+                        | ${SED} 10q \
+                        | $EGREP "$file_magic_regex" > /dev/null; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               $echo
+               $echo "*** Warning: linker path does not have real file for library $a_deplib."
+               $echo "*** I have the capability to make that library automatically link in when"
+               $echo "*** you link to this library.  But I can only do this if you have a"
+               $echo "*** shared version of the library, which you do not appear to have"
+               $echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $echo "*** with $libname but no candidates were found. (...for file magic test)"
+               else
+                 $echo "*** with $libname and none of the candidates passed a file format test"
+                 $echo "*** using a file magic. Last file checked: $potlib"
+               fi
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       match_pattern*)
+         set dummy $deplibs_check_method
+         match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+         for a_deplib in $deplibs; do
+           name="`expr $a_deplib : '-l\(.*\)'`"
+           # If $name is empty we are operating on a -L argument.
+           if test -n "$name" && test "$name" != "0"; then
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 newdeplibs="$newdeplibs $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 for potent_lib in $potential_libs; do
+                   potlib="$potent_lib" # see symlink-check above in file_magic test
+                   if eval $echo \"$potent_lib\" 2>/dev/null \
+                       | ${SED} 10q \
+                       | $EGREP "$match_pattern_regex" > /dev/null; then
+                     newdeplibs="$newdeplibs $a_deplib"
+                     a_deplib=""
+                     break 2
+                   fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               $echo
+               $echo "*** Warning: linker path does not have real file for library $a_deplib."
+               $echo "*** I have the capability to make that library automatically link in when"
+               $echo "*** you link to this library.  But I can only do this if you have a"
+               $echo "*** shared version of the library, which you do not appear to have"
+               $echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+               else
+                 $echo "*** with $libname and none of the candidates passed a file format test"
+                 $echo "*** using a regex pattern. Last file checked: $potlib"
+               fi
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       none | unknown | *)
+         newdeplibs=""
+         tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+           -e 's/ -[LR][^ ]*//g'`
+         if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+           for i in $predeps $postdeps ; do
+             # can't use Xsed below, because $i might contain '/'
+             tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+           done
+         fi
+         if $echo "X $tmp_deplibs" | $Xsed -e 's/[     ]//g' \
+           | grep . >/dev/null; then
+           $echo
+           if test "X$deplibs_check_method" = "Xnone"; then
+             $echo "*** Warning: inter-library dependencies are not supported in this platform."
+           else
+             $echo "*** Warning: inter-library dependencies are not known to be supported."
+           fi
+           $echo "*** All declared inter-library dependencies are being dropped."
+           droppeddeps=yes
+         fi
+         ;;
+       esac
+       versuffix=$versuffix_save
+       major=$major_save
+       release=$release_save
+       libname=$libname_save
+       name=$name_save
+
+       case $host in
+       *-*-rhapsody* | *-*-darwin1.[012])
+         # On Rhapsody replace the C library is the System framework
+         newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+         ;;
+       esac
+
+       if test "$droppeddeps" = yes; then
+         if test "$module" = yes; then
+           $echo
+           $echo "*** Warning: libtool could not satisfy all declared inter-library"
+           $echo "*** dependencies of module $libname.  Therefore, libtool will create"
+           $echo "*** a static module, that should work as long as the dlopening"
+           $echo "*** application is linked with the -dlopen flag."
+           if test -z "$global_symbol_pipe"; then
+             $echo
+             $echo "*** However, this would only work if libtool was able to extract symbol"
+             $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             $echo "*** not find such a program.  So, this module is probably useless."
+             $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+           fi
+           if test "$build_old_libs" = no; then
+             oldlibs="$output_objdir/$libname.$libext"
+             build_libtool_libs=module
+             build_old_libs=yes
+           else
+             build_libtool_libs=no
+           fi
+         else
+           $echo "*** The inter-library dependencies that have been dropped here will be"
+           $echo "*** automatically added whenever a program is linked with this library"
+           $echo "*** or is declared to -dlopen it."
+
+           if test "$allow_undefined" = no; then
+             $echo
+             $echo "*** Since this library must not contain undefined symbols,"
+             $echo "*** because either the platform does not support them or"
+             $echo "*** it was explicitly requested with -no-undefined,"
+             $echo "*** libtool will only create a static version of it."
+             if test "$build_old_libs" = no; then
+               oldlibs="$output_objdir/$libname.$libext"
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         fi
+       fi
+       # Done checking deplibs!
+       deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+       if test "$hardcode_into_libs" = yes; then
+         # Hardcode the library paths
+         hardcode_libdirs=
+         dep_rpath=
+         rpath="$finalize_rpath"
+         test "$mode" != relink && rpath="$compile_rpath$rpath"
+         for libdir in $rpath; do
+           if test -n "$hardcode_libdir_flag_spec"; then
+             if test -n "$hardcode_libdir_separator"; then
+               if test -z "$hardcode_libdirs"; then
+                 hardcode_libdirs="$libdir"
+               else
+                 # Just accumulate the unique libdirs.
+                 case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+                 *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                   ;;
+                 *)
+                   hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                   ;;
+                 esac
+               fi
+             else
+               eval flag=\"$hardcode_libdir_flag_spec\"
+               dep_rpath="$dep_rpath $flag"
+             fi
+           elif test -n "$runpath_var"; then
+             case "$perm_rpath " in
+             *" $libdir "*) ;;
+             *) perm_rpath="$perm_rpath $libdir" ;;
+             esac
+           fi
+         done
+         # Substitute the hardcoded libdirs into the rpath.
+         if test -n "$hardcode_libdir_separator" &&
+            test -n "$hardcode_libdirs"; then
+           libdir="$hardcode_libdirs"
+           if test -n "$hardcode_libdir_flag_spec_ld"; then
+             eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+           else
+             eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+           fi
+         fi
+         if test -n "$runpath_var" && test -n "$perm_rpath"; then
+           # We should set the runpath_var.
+           rpath=
+           for dir in $perm_rpath; do
+             rpath="$rpath$dir:"
+           done
+           eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+         fi
+         test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+       fi
+
+       shlibpath="$finalize_shlibpath"
+       test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+       if test -n "$shlibpath"; then
+         eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+       fi
+
+       # Get the real and link names of the library.
+       eval shared_ext=\"$shrext_cmds\"
+       eval library_names=\"$library_names_spec\"
+       set dummy $library_names
+       realname="$2"
+       shift; shift
+
+       if test -n "$soname_spec"; then
+         eval soname=\"$soname_spec\"
+       else
+         soname="$realname"
+       fi
+       if test -z "$dlname"; then
+         dlname=$soname
+       fi
+
+       lib="$output_objdir/$realname"
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+       # Use standard objects if they are pic
+       test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           cmds=$export_symbols_cmds
+           save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             eval cmd=\"$cmd\"
+             if len=`expr "X$cmd" : ".*"` &&
+              test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+               skipped_export=false
+             else
+               # The command line is too long to execute in one step.
+               $show "using reloadable object file for export list..."
+               skipped_export=:
+             fi
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex"; then
+             $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+             $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+             $run eval '$mv "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+       fi
+
+       tmp_deplibs=
+       for test_deplib in $deplibs; do
+               case " $convenience " in
+               *" $test_deplib "*) ;;
+               *)
+                       tmp_deplibs="$tmp_deplibs $test_deplib"
+                       ;;
+               esac
+       done
+       deplibs="$tmp_deplibs"
+
+       if test -n "$convenience"; then
+         if test -n "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         else
+           gentop="$output_objdir/${outputname}x"
+           $show "${rm}r $gentop"
+           $run ${rm}r "$gentop"
+           $show "$mkdir $gentop"
+           $run $mkdir "$gentop"
+           status=$?
+           if test "$status" -ne 0 && test ! -d "$gentop"; then
+             exit $status
+           fi
+           generated="$generated $gentop"
+
+           for xlib in $convenience; do
+             # Extract the objects.
+             case $xlib in
+             [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+             *) xabs=`pwd`"/$xlib" ;;
+             esac
+             xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+             xdir="$gentop/$xlib"
+
+             $show "${rm}r $xdir"
+             $run ${rm}r "$xdir"
+             $show "$mkdir $xdir"
+             $run $mkdir "$xdir"
+             status=$?
+             if test "$status" -ne 0 && test ! -d "$xdir"; then
+               exit $status
+             fi
+             # We will extract separately just the conflicting names and we will no
+             # longer touch any unique names. It is faster to leave these extract
+             # automatically by $AR in one run.
+             $show "(cd $xdir && $AR x $xabs)"
+             $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+             if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+               :
+             else
+               $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+               $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+               $AR t "$xabs" | sort | uniq -cd | while read -r count name
+               do
+                 i=1
+                 while test "$i" -le "$count"
+                 do
+                  # Put our $i before any first dot (extension)
+                  # Never overwrite any file
+                  name_to="$name"
+                  while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+                  do
+                    name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+                  done
+                  $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+                  $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+                  i=`expr $i + 1`
+                 done
+               done
+             fi
+
+             libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+           done
+         fi
+       fi
+
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+         eval flag=\"$thread_safe_flag_spec\"
+         linker_flags="$linker_flags $flag"
+       fi
+
+       # Make a backup of the uninstalled library when relinking
+       if test "$mode" = relink; then
+         $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+       fi
+
+       # Do each of the archive commands.
+       if test "$module" = yes && test -n "$module_cmds" ; then
+         if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+           eval test_cmds=\"$module_expsym_cmds\"
+           cmds=$module_expsym_cmds
+         else
+           eval test_cmds=\"$module_cmds\"
+           cmds=$module_cmds
+         fi
+       else
+       if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+         eval test_cmds=\"$archive_expsym_cmds\"
+         cmds=$archive_expsym_cmds
+       else
+         eval test_cmds=\"$archive_cmds\"
+         cmds=$archive_cmds
+         fi
+       fi
+
+       if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` &&
+          test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         :
+       else
+         # The command line is too long to link in one step, link piecewise.
+         $echo "creating reloadable object files..."
+
+         # Save the value of $output and $libobjs because we want to
+         # use them later.  If we have whole_archive_flag_spec, we
+         # want to use save_libobjs as it was before
+         # whole_archive_flag_spec was expanded, because we can't
+         # assume the linker understands whole_archive_flag_spec.
+         # This may have to be revisited, in case too many
+         # convenience libraries get linked in and end up exceeding
+         # the spec.
+         if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+         fi
+         save_output=$output
+
+         # Clear the reloadable object creation command queue and
+         # initialize k to one.
+         test_cmds=
+         concat_cmds=
+         objlist=
+         delfiles=
+         last_robj=
+         k=1
+         output=$output_objdir/$save_output-${k}.$objext
+         # Loop over the list of objects to be linked.
+         for obj in $save_libobjs
+         do
+           eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+           if test "X$objlist" = X ||
+              { len=`expr "X$test_cmds" : ".*"` &&
+                test "$len" -le "$max_cmd_len"; }; then
+             objlist="$objlist $obj"
+           else
+             # The command $test_cmds is almost too long, add a
+             # command to the queue.
+             if test "$k" -eq 1 ; then
+               # The first file doesn't have a previous command to add.
+               eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+             else
+               # All subsequent reloadable object files will link in
+               # the last one created.
+               eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+             fi
+             last_robj=$output_objdir/$save_output-${k}.$objext
+             k=`expr $k + 1`
+             output=$output_objdir/$save_output-${k}.$objext
+             objlist=$obj
+             len=1
+           fi
+         done
+         # Handle the remaining objects by creating one last
+         # reloadable object file.  All subsequent reloadable object
+         # files will link in the last one created.
+         test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+         eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+         if ${skipped_export-false}; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           libobjs=$output
+           # Append the command to create the export file.
+           eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+          fi
+
+         # Set up a command to remove the reloadale object files
+         # after they are used.
+         i=0
+         while test "$i" -lt "$k"
+         do
+           i=`expr $i + 1`
+           delfiles="$delfiles $output_objdir/$save_output-${i}.$objext"
+         done
+
+         $echo "creating a temporary reloadable object file: $output"
+
+         # Loop through the commands generated above and execute them.
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $concat_cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || exit $?
+         done
+         IFS="$save_ifs"
+
+         libobjs=$output
+         # Restore the value of output.
+         output=$save_output
+
+         if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         fi
+         # Expand the library linking commands again to reset the
+         # value of $libobjs for piecewise linking.
+
+         # Do each of the archive commands.
+         if test "$module" = yes && test -n "$module_cmds" ; then
+           if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+             cmds=$module_expsym_cmds
+           else
+             cmds=$module_cmds
+           fi
+         else
+         if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+           cmds=$archive_expsym_cmds
+         else
+           cmds=$archive_cmds
+           fi
+         fi
+
+         # Append the command to remove the reloadable object files
+         # to the just-reset $cmds.
+         eval cmds=\"\$cmds~\$rm $delfiles\"
+       fi
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+
+       # Restore the uninstalled library and exit
+       if test "$mode" = relink; then
+         $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+         exit $EXIT_SUCCESS
+       fi
+
+       # Create links to the real library.
+       for linkname in $linknames; do
+         if test "$realname" != "$linkname"; then
+           $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+           $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+         fi
+       done
+
+       # If -module or -export-dynamic was specified, set the dlname.
+       if test "$module" = yes || test "$export_dynamic" = yes; then
+         # On all known operating systems, these are identical.
+         dlname="$soname"
+       fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case $output in
+      *.lo)
+       if test -n "$objs$old_deplibs"; then
+         $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       libobj="$output"
+       obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+       ;;
+      *)
+       libobj=
+       obj="$output"
+       ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl=
+
+      if test -n "$convenience"; then
+       if test -n "$whole_archive_flag_spec"; then
+         eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+       else
+         gentop="$output_objdir/${obj}x"
+         $show "${rm}r $gentop"
+         $run ${rm}r "$gentop"
+         $show "$mkdir $gentop"
+         $run $mkdir "$gentop"
+         status=$?
+         if test "$status" -ne 0 && test ! -d "$gentop"; then
+           exit $status
+         fi
+         generated="$generated $gentop"
+
+         for xlib in $convenience; do
+           # Extract the objects.
+           case $xlib in
+           [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+           *) xabs=`pwd`"/$xlib" ;;
+           esac
+           xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+           xdir="$gentop/$xlib"
+
+           $show "${rm}r $xdir"
+           $run ${rm}r "$xdir"
+           $show "$mkdir $xdir"
+           $run $mkdir "$xdir"
+           status=$?
+           if test "$status" -ne 0 && test ! -d "$xdir"; then
+             exit $status
+           fi
+           # We will extract separately just the conflicting names and we will no
+           # longer touch any unique names. It is faster to leave these extract
+           # automatically by $AR in one run.
+           $show "(cd $xdir && $AR x $xabs)"
+           $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+           if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+             :
+           else
+             $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+             $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+             $AR t "$xabs" | sort | uniq -cd | while read -r count name
+             do
+               i=1
+               while test "$i" -le "$count"
+               do
+                # Put our $i before any first dot (extension)
+                # Never overwrite any file
+                name_to="$name"
+                while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+                do
+                  name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+                done
+                $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+                $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+                i=`expr $i + 1`
+               done
+             done
+           fi
+
+           reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+         done
+       fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      cmds=$reload_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       eval cmd=\"$cmd\"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       # Create an invalid libtool object if no PIC, so that we don't
+       # accidentally link it into a program.
+       # $show "echo timestamp > $libobj"
+       # $run eval "echo timestamp > $libobj" || exit $?
+       exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+       # Only do commands if we really have different PIC objects.
+       reload_objs="$libobjs $reload_conv_objs"
+       output="$libobj"
+       cmds=$reload_cmds
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+      fi
+
+      if test -n "$gentop"; then
+       $show "${rm}r $gentop"
+       $run ${rm}r $gentop
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+       *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
+      esac
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+       if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+          test "$dlopen_self_static" = unknown; then
+         $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+       fi
+      fi
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+       # On Rhapsody replace the C library is the System framework
+       compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+       finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+       ;;
+      esac
+
+      case $host in
+      *darwin*)
+        # Don't allow lazy linking, it breaks C++ global constructors
+        if test "$tagname" = CXX ; then
+        compile_command="$compile_command ${wl}-bind_at_load"
+        finalize_command="$finalize_command ${wl}-bind_at_load"
+        fi
+        ;;
+      esac
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath $xrpath; do
+         # This is the magic to use -rpath.
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$perm_rpath " in
+         *" $libdir "*) ;;
+         *) perm_rpath="$perm_rpath $libdir" ;;
+         esac
+       fi
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         case :$dllsearchpath: in
+         *":$libdir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$libdir";;
+         esac
+         ;;
+       esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$finalize_perm_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+       # Transform all the library objects into standard objects.
+       compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       if test -n "$NM" && test -n "$global_symbol_pipe"; then
+         dlsyms="${outputname}S.c"
+       else
+         $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+       fi
+      fi
+
+      if test -n "$dlsyms"; then
+       case $dlsyms in
+       "") ;;
+       *.c)
+         # Discover the nlist of each of the dlfiles.
+         nlist="$output_objdir/${outputname}.nm"
+
+         $show "$rm $nlist ${nlist}S ${nlist}T"
+         $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+         # Parse the name list into a source file.
+         $show "creating $output_objdir/$dlsyms"
+
+         test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+         if test "$dlself" = yes; then
+           $show "generating symbol list for \`$output'"
+
+           test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+           # Add our own program objects to the symbol list.
+           progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+           for arg in $progfiles; do
+             $show "extracting global C symbols from \`$arg'"
+             $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+           done
+
+           if test -n "$exclude_expsyms"; then
+             $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           if test -n "$export_symbols_regex"; then
+             $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           # Prepare the list of exported symbols
+           if test -z "$export_symbols"; then
+             export_symbols="$output_objdir/$output.exp"
+             $run $rm $export_symbols
+             $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+           else
+             $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+             $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+             $run eval 'mv "$nlist"T "$nlist"'
+           fi
+         fi
+
+         for arg in $dlprefiles; do
+           $show "extracting global C symbols from \`$arg'"
+           name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+           $run eval '$echo ": $name " >> "$nlist"'
+           $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+         done
+
+         if test -z "$run"; then
+           # Make sure we have at least an empty file.
+           test -f "$nlist" || : > "$nlist"
+
+           if test -n "$exclude_expsyms"; then
+             $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+             $mv "$nlist"T "$nlist"
+           fi
+
+           # Try sorting and uniquifying the output.
+           if grep -v "^: " < "$nlist" |
+               if sort -k 3 </dev/null >/dev/null 2>&1; then
+                 sort -k 3
+               else
+                 sort +2
+               fi |
+               uniq > "$nlist"S; then
+             :
+           else
+             grep -v "^: " < "$nlist" > "$nlist"S
+           fi
+
+           if test -f "$nlist"S; then
+             eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+           else
+             $echo '/* NONE */' >> "$output_objdir/$dlsyms"
+           fi
+
+           $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+           $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+         fi
+
+         pic_flag_for_symtable=
+         case $host in
+         # compiling the symbol table file with pic_flag works around
+         # a FreeBSD bug that causes programs to crash when -lm is
+         # linked before any other PIC object.  But we must not use
+         # pic_flag when linking with -static.  The problem exists in
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
+           esac;;
+         *-*-hpux*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag";;
+           esac
+         esac
+
+         # Now compile the dynamic symbol file.
+         $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+         $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+         # Clean up the generated files.
+         $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+         $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+         # Transform the symbol file into the correct name.
+         compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         ;;
+       *)
+         $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+      else
+       # We keep going just in case the user didn't refer to
+       # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+       # really was required.
+
+       # Nullify the symbol file.
+       compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+       # Replace the output file specification.
+       compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       link_command="$compile_command$compile_rpath"
+
+       # We have no uninstalled library dependencies, so finalize right now.
+       $show "$link_command"
+       $run eval "$link_command"
+       status=$?
+
+       # Delete the generated files.
+       if test -n "$dlsyms"; then
+         $show "$rm $output_objdir/${outputname}S.${objext}"
+         $run $rm "$output_objdir/${outputname}S.${objext}"
+       fi
+
+       exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+       # We should set the shlibpath_var
+       rpath=
+       for dir in $temp_rpath; do
+         case $dir in
+         [\\/]* | [A-Za-z]:[\\/]*)
+           # Absolute path.
+           rpath="$rpath$dir:"
+           ;;
+         *)
+           # Relative path: add a thisdir entry.
+           rpath="$rpath\$thisdir/$dir:"
+           ;;
+         esac
+       done
+       temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+       if test -n "$perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+       if test -n "$finalize_perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $finalize_perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+      fi
+
+      if test "$no_install" = yes; then
+       # We don't need to create a wrapper script.
+       link_command="$compile_var$compile_command$compile_rpath"
+       # Replace the output file specification.
+       link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       # Delete the old output file.
+       $run $rm $output
+       # Link the executable and exit
+       $show "$link_command"
+       $run eval "$link_command" || exit $?
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+       # Fast installation is not supported
+       link_command="$compile_var$compile_command$compile_rpath"
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+       $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+       $echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+       if test "$fast_install" != no; then
+         link_command="$finalize_var$compile_command$finalize_rpath"
+         if test "$fast_install" = yes; then
+           relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+         else
+           # fast_install is set to needless
+           relink_command=
+         fi
+       else
+         link_command="$compile_var$compile_command$compile_rpath"
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
+       fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+       # Preserve any variables that may affect compiler behavior
+       for var in $variables_saved_for_relink; do
+         if eval test -z \"\${$var+set}\"; then
+           relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+         elif eval var_value=\$$var; test -z "$var_value"; then
+           relink_command="$var=; export $var; $relink_command"
+         else
+           var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+           relink_command="$var=\"$var_value\"; export $var; $relink_command"
+         fi
+       done
+       relink_command="(cd `pwd`; $relink_command)"
+       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
+       case $progpath in
+       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+       *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+       esac
+       qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+       qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+       # win32 will think the script is a binary if it has
+       # a .exe suffix, so we strip it off here.
+       case $output in
+         *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
+       esac
+       # test for cygwin because mv fails w/o .exe extensions
+       case $host in
+         *cygwin*)
+           exeext=.exe
+           outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
+         *) exeext= ;;
+       esac
+       case $host in
+         *cygwin* | *mingw* )
+           cwrappersource=`$echo ${objdir}/lt-${output}.c`
+           cwrapper=`$echo ${output}.exe`
+           $rm $cwrappersource $cwrapper
+           trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+           cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "/bin/sh $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+           cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+#define HAVE_DOS_BASED_FILE_SYSTEM
+#ifndef DIR_SEPARATOR_2
+#define DIR_SEPARATOR_2 '\\'
+#endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+char * basename (const char *name);
+char * fnqualify(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int i;
+
+  program_name = (char *) xstrdup ((char *) basename (argv[0]));
+  newargz = XMALLOC(char *, argc+2);
+EOF
+
+           cat >> $cwrappersource <<EOF
+  newargz[0] = "$SHELL";
+EOF
+
+           cat >> $cwrappersource <<"EOF"
+  newargz[1] = fnqualify(argv[0]);
+  /* we know the script has the same name, without the .exe */
+  /* so make sure newargz[1] doesn't end in .exe */
+  strendzap(newargz[1],".exe");
+  for (i = 1; i < argc; i++)
+    newargz[i+1] = xstrdup(argv[i]);
+  newargz[argc+1] = NULL;
+EOF
+
+           cat >> $cwrappersource <<EOF
+  execv("$SHELL",newargz);
+EOF
+
+           cat >> $cwrappersource <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void * p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+char *
+basename (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha (name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return (char *) base;
+}
+
+char *
+fnqualify(const char *path)
+{
+  size_t size;
+  char *p;
+  char tmp[LT_PATHMAX + 1];
+
+  assert(path != NULL);
+
+  /* Is it qualified already? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha (path[0]) && path[1] == ':')
+    return xstrdup (path);
+#endif
+  if (IS_DIR_SEPARATOR (path[0]))
+    return xstrdup (path);
+
+  /* prepend the current directory */
+  /* doesn't handle '~' */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
+  p = XMALLOC(char, size);
+  sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
+  return p;
+}
+
+char *
+strendzap(char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert(str != NULL);
+  assert(pat != NULL);
+
+  len = strlen(str);
+  patlen = strlen(pat);
+
+  if (patlen <= len)
+  {
+    str += len - patlen;
+    if (strcmp(str, pat) == 0)
+      *str = '\0';
+  }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode,
+          const char * message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+EOF
+         # we should really use a build-platform specific compiler
+         # here, but OTOH, the wrappers (shell script and this C one)
+         # are only useful if you want to execute the "real" binary.
+         # Since the "real" binary is built for $host, then this
+         # wrapper might as well be built for $host, too.
+         $run $LTCC -s -o $cwrapper $cwrappersource
+         ;;
+       esac
+       $rm $output
+       trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+
+       $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+       $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+       if test "$fast_install" = yes; then
+         $echo >> $output "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+         $echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+       $echo \"\$relink_command_output\" >&2
+       $rm \"\$progdir/\$file\"
+       exit $EXIT_FAILURE
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+       else
+         $echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+       fi
+
+       $echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+       # Export our shlibpath_var if we have one.
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+         $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+       fi
+
+       # fixup the dll searchpath if we need to.
+       if test -n "$dllsearchpath"; then
+         $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
+       $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+       case $host in
+       # Backslashes separate directories on plain windows
+       *-*-mingw | *-*-os2*)
+         $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+         ;;
+
+       *)
+         $echo >> $output "\
+      exec \$progdir/\$program \${1+\"\$@\"}
+"
+         ;;
+       esac
+       $echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit $EXIT_FAILURE
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi\
+"
+       chmod +x $output
+      fi
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+       oldobjs="$libobjs_save"
+       addlibs="$convenience"
+       build_libtool_libs=no
+      else
+       if test "$build_libtool_libs" = module; then
+         oldobjs="$libobjs_save"
+         build_libtool_libs=no
+       else
+         oldobjs="$old_deplibs $non_pic_objects"
+       fi
+       addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+       gentop="$output_objdir/${outputname}x"
+       $show "${rm}r $gentop"
+       $run ${rm}r "$gentop"
+       $show "$mkdir $gentop"
+       $run $mkdir "$gentop"
+       status=$?
+       if test "$status" -ne 0 && test ! -d "$gentop"; then
+         exit $status
+       fi
+       generated="$generated $gentop"
+
+       # Add in members from convenience archives.
+       for xlib in $addlibs; do
+         # Extract the objects.
+         case $xlib in
+         [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+         *) xabs=`pwd`"/$xlib" ;;
+         esac
+         xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+         xdir="$gentop/$xlib"
+
+         $show "${rm}r $xdir"
+         $run ${rm}r "$xdir"
+         $show "$mkdir $xdir"
+         $run $mkdir "$xdir"
+         status=$?
+         if test "$status" -ne 0 && test ! -d "$xdir"; then
+           exit $status
+         fi
+         # We will extract separately just the conflicting names and we will no
+         # longer touch any unique names. It is faster to leave these extract
+         # automatically by $AR in one run.
+         $show "(cd $xdir && $AR x $xabs)"
+         $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+         if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+           :
+         else
+           $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+           $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+           $AR t "$xabs" | sort | uniq -cd | while read -r count name
+           do
+             i=1
+             while test "$i" -le "$count"
+             do
+              # Put our $i before any first dot (extension)
+              # Never overwrite any file
+              name_to="$name"
+              while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+              do
+                name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+              done
+              $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+              $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+              i=`expr $i + 1`
+             done
+           done
+         fi
+
+         oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+       done
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=$old_archive_from_new_cmds
+      else
+       eval cmds=\"$old_archive_cmds\"
+
+       if len=`expr "X$cmds" : ".*"` &&
+            test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         cmds=$old_archive_cmds
+       else
+         # the command line is too long to link in one step, link in parts
+         $echo "using piecewise archive linking..."
+         save_RANLIB=$RANLIB
+         RANLIB=:
+         objlist=
+         concat_cmds=
+         save_oldobjs=$oldobjs
+         # GNU ar 2.10+ was changed to match POSIX; thus no paths are
+         # encoded into archives.  This makes 'ar r' malfunction in
+         # this piecewise linking case whenever conflicting object
+         # names appear in distinct ar calls; check, warn and compensate.
+           if (for obj in $save_oldobjs
+           do
+             $echo "X$obj" | $Xsed -e 's%^.*/%%'
+           done | sort | sort -uc >/dev/null 2>&1); then
+           :
+         else
+           $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2
+           $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2
+           AR_FLAGS=cq
+         fi
+         # Is there a better way of finding the last object in the list?
+         for obj in $save_oldobjs
+         do
+           last_oldobj=$obj
+         done
+         for obj in $save_oldobjs
+         do
+           oldobjs="$objlist $obj"
+           objlist="$objlist $obj"
+           eval test_cmds=\"$old_archive_cmds\"
+           if len=`expr "X$test_cmds" : ".*"` &&
+              test "$len" -le "$max_cmd_len"; then
+             :
+           else
+             # the above command should be used before it gets too long
+             oldobjs=$objlist
+             if test "$obj" = "$last_oldobj" ; then
+               RANLIB=$save_RANLIB
+             fi
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+             eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+             objlist=
+           fi
+         done
+         RANLIB=$save_RANLIB
+         oldobjs=$objlist
+         if test "X$oldobjs" = "X" ; then
+           eval cmds=\"\$concat_cmds\"
+         else
+           eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+         fi
+       fi
+      fi
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+        eval cmd=\"$cmd\"
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+       if eval test -z \"\${$var+set}\"; then
+         relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+       elif eval var_value=\$$var; test -z "$var_value"; then
+         relink_command="$var=; export $var; $relink_command"
+       else
+         var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+         relink_command="$var=\"$var_value\"; export $var; $relink_command"
+       fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+       relink_command=
+      fi
+
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+       for installed in no yes; do
+         if test "$installed" = yes; then
+           if test -z "$install_libdir"; then
+             break
+           fi
+           output="$output_objdir/$outputname"i
+           # Replace all uninstalled libtool libraries with the installed ones
+           newdependency_libs=
+           for deplib in $dependency_libs; do
+             case $deplib in
+             *.la)
+               name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+               if test -z "$libdir"; then
+                 $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+                 exit $EXIT_FAILURE
+               fi
+               newdependency_libs="$newdependency_libs $libdir/$name"
+               ;;
+             *) newdependency_libs="$newdependency_libs $deplib" ;;
+             esac
+           done
+           dependency_libs="$newdependency_libs"
+           newdlfiles=
+           for lib in $dlfiles; do
+             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+             eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+             if test -z "$libdir"; then
+               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+               exit $EXIT_FAILURE
+             fi
+             newdlfiles="$newdlfiles $libdir/$name"
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+             eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+             if test -z "$libdir"; then
+               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+               exit $EXIT_FAILURE
+             fi
+             newdlprefiles="$newdlprefiles $libdir/$name"
+           done
+           dlprefiles="$newdlprefiles"
+         else
+           newdlfiles=
+           for lib in $dlfiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             newdlfiles="$newdlfiles $abs"
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             newdlprefiles="$newdlprefiles $abs"
+           done
+           dlprefiles="$newdlprefiles"
+         fi
+         $rm $output
+         # place dlname in correct position for cygwin
+         tdlname=$dlname
+         case $host,$output,$installed,$module,$dlname in
+           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+         esac
+         $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+         if test "$installed" = no && test "$need_relink" = yes; then
+           $echo >> $output "\
+relink_command=\"$relink_command\""
+         fi
+       done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case $arg in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+       files="$files $dest"
+       dest="$arg"
+       continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+       stripme=" -s"
+       continue
+       ;;
+      -*) ;;
+
+      *)
+       # If the previous option needed an argument, then skip it.
+       if test -n "$prev"; then
+         prev=
+       else
+         dest="$arg"
+         continue
+       fi
+       ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+       $echo "$modename: no file or destination specified" 1>&2
+      else
+       $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test "$#" -gt 2; then
+       $echo "$modename: \`$dest' is not a directory" 1>&2
+       $echo "$help" 1>&2
+       exit $EXIT_FAILURE
+      fi
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+       case $file in
+       *.lo) ;;
+       *)
+         $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+       # Do the static libraries later.
+       staticlibs="$staticlibs $file"
+       ;;
+
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       library_names=
+       old_library=
+       relink_command=
+       # If there is no directory component, then add one.
+       case $file in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Add the libdir to current_libdirs if it is the destination.
+       if test "X$destdir" = "X$libdir"; then
+         case "$current_libdirs " in
+         *" $libdir "*) ;;
+         *) current_libdirs="$current_libdirs $libdir" ;;
+         esac
+       else
+         # Note the libdir as a future libdir.
+         case "$future_libdirs " in
+         *" $libdir "*) ;;
+         *) future_libdirs="$future_libdirs $libdir" ;;
+         esac
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+       test "X$dir" = "X$file/" && dir=
+       dir="$dir$objdir"
+
+       if test -n "$relink_command"; then
+         # Determine the prefix the user has applied to our future dir.
+         inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+         # Don't allow the user to place us outside of our expected
+         # location b/c this prevents finding dependent libraries that
+         # are installed to the same prefix.
+         # At present, this check doesn't affect windows .dll's that
+         # are installed into $libdir/../bin (currently, that works fine)
+         # but it's something to keep an eye on.
+         if test "$inst_prefix_dir" = "$destdir"; then
+           $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         if test -n "$inst_prefix_dir"; then
+           # Stick the inst_prefix_dir data into the link command.
+           relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+         else
+           relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+         fi
+
+         $echo "$modename: warning: relinking \`$file'" 1>&2
+         $show "$relink_command"
+         if $run eval "$relink_command"; then :
+         else
+           $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+           exit $EXIT_FAILURE
+         fi
+       fi
+
+       # See the names of the shared library.
+       set dummy $library_names
+       if test -n "$2"; then
+         realname="$2"
+         shift
+         shift
+
+         srcname="$realname"
+         test -n "$relink_command" && srcname="$realname"T
+
+         # Install the shared library and build the symlinks.
+         $show "$install_prog $dir/$srcname $destdir/$realname"
+         $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+         if test -n "$stripme" && test -n "$striplib"; then
+           $show "$striplib $destdir/$realname"
+           $run eval "$striplib $destdir/$realname" || exit $?
+         fi
+
+         if test "$#" -gt 0; then
+           # Delete the old symlinks, and create new ones.
+           for linkname
+           do
+             if test "$linkname" != "$realname"; then
+               $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+               $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+             fi
+           done
+         fi
+
+         # Do each command in the postinstall commands.
+         lib="$destdir/$realname"
+         cmds=$postinstall_cmds
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           eval cmd=\"$cmd\"
+           $show "$cmd"
+           $run eval "$cmd" || exit $?
+         done
+         IFS="$save_ifs"
+       fi
+
+       # Install the pseudo-library for information purposes.
+       name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+       instname="$dir/$name"i
+       $show "$install_prog $instname $destdir/$name"
+       $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+       # Maybe install the static library, too.
+       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       ;;
+
+      *.lo)
+       # Install (i.e. copy) a libtool object.
+
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Deduce the name of the destination old-style object file.
+       case $destfile in
+       *.lo)
+         staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+         ;;
+       *.$objext)
+         staticdest="$destfile"
+         destfile=
+         ;;
+       *)
+         $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       # Install the libtool object if requested.
+       if test -n "$destfile"; then
+         $show "$install_prog $file $destfile"
+         $run eval "$install_prog $file $destfile" || exit $?
+       fi
+
+       # Install the old object if enabled.
+       if test "$build_old_libs" = yes; then
+         # Deduce the name of the old-style object file.
+         staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+         $show "$install_prog $staticobj $staticdest"
+         $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+       fi
+       exit $EXIT_SUCCESS
+       ;;
+
+      *)
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # If the file is missing, and there is a .exe on the end, strip it
+       # because it is most likely a libtool script we actually want to
+       # install
+       stripped_ext=""
+       case $file in
+         *.exe)
+           if test ! -f "$file"; then
+             file=`$echo $file|${SED} 's,.exe$,,'`
+             stripped_ext=".exe"
+           fi
+           ;;
+       esac
+
+       # Do a test to see if this is really a libtool program.
+       case $host in
+       *cygwin*|*mingw*)
+           wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+           ;;
+       *)
+           wrapper=$file
+           ;;
+       esac
+       if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+         notinst_deplibs=
+         relink_command=
+
+         # To insure that "foo" is sourced, and not "foo.exe",
+         # finese the cygwin/MSYS system by explicitly sourcing "foo."
+         # which disallows the automatic-append-.exe behavior.
+         case $build in
+         *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+         *) wrapperdot=${wrapper} ;;
+         esac
+         # If there is no directory component, then add one.
+         case $file in
+         */* | *\\*) . ${wrapperdot} ;;
+         *) . ./${wrapperdot} ;;
+         esac
+
+         # Check the variables that should have been set.
+         if test -z "$notinst_deplibs"; then
+           $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         finalize=yes
+         for lib in $notinst_deplibs; do
+           # Check to see that each library is installed.
+           libdir=
+           if test -f "$lib"; then
+             # If there is no directory component, then add one.
+             case $lib in
+             */* | *\\*) . $lib ;;
+             *) . ./$lib ;;
+             esac
+           fi
+           libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+           if test -n "$libdir" && test ! -f "$libfile"; then
+             $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+             finalize=no
+           fi
+         done
+
+         relink_command=
+         # To insure that "foo" is sourced, and not "foo.exe",
+         # finese the cygwin/MSYS system by explicitly sourcing "foo."
+         # which disallows the automatic-append-.exe behavior.
+         case $build in
+         *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+         *) wrapperdot=${wrapper} ;;
+         esac
+         # If there is no directory component, then add one.
+         case $file in
+         */* | *\\*) . ${wrapperdot} ;;
+         *) . ./${wrapperdot} ;;
+         esac
+
+         outputname=
+         if test "$fast_install" = no && test -n "$relink_command"; then
+           if test "$finalize" = yes && test -z "$run"; then
+             tmpdir="/tmp"
+             test -n "$TMPDIR" && tmpdir="$TMPDIR"
+             tmpdir="$tmpdir/libtool-$$"
+             save_umask=`umask`
+             umask 0077
+             if $mkdir "$tmpdir"; then
+               umask $save_umask
+             else
+               umask $save_umask
+               $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+               continue
+             fi
+             file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
+             outputname="$tmpdir/$file"
+             # Replace the output file specification.
+             relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+             $show "$relink_command"
+             if $run eval "$relink_command"; then :
+             else
+               $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+               ${rm}r "$tmpdir"
+               continue
+             fi
+             file="$outputname"
+           else
+             $echo "$modename: warning: cannot relink \`$file'" 1>&2
+           fi
+         else
+           # Install the binary that we compiled earlier.
+           file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+         fi
+       fi
+
+       # remove .exe since cygwin /usr/bin/install will append another
+       # one anyways
+       case $install_prog,$host in
+       */usr/bin/install*,*cygwin*)
+         case $file:$destfile in
+         *.exe:*.exe)
+           # this is ok
+           ;;
+         *.exe:*)
+           destfile=$destfile.exe
+           ;;
+         *:*.exe)
+           destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
+           ;;
+         esac
+         ;;
+       esac
+       $show "$install_prog$stripme $file $destfile"
+       $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+       test -n "$outputname" && ${rm}r "$tmpdir"
+       ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+       $show "$old_striplib $oldlib"
+       $run eval "$old_striplib $oldlib" || exit $?
+      fi
+
+      # Do each command in the postinstall commands.
+      cmds=$old_postinstall_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       eval cmd=\"$cmd\"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+       libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         cmds=$finish_cmds
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           eval cmd=\"$cmd\"
+           $show "$cmd"
+           $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+         done
+         IFS="$save_ifs"
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+       fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit $EXIT_SUCCESS
+
+    $echo "----------------------------------------------------------------------"
+    $echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $echo "   $libdir"
+    done
+    $echo
+    $echo "If you ever happen to want to link against installed libraries"
+    $echo "in a given directory, LIBDIR, you must either use libtool, and"
+    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $echo
+    $echo "See any operating system documentation about shared libraries for"
+    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    $echo "----------------------------------------------------------------------"
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit $EXIT_FAILURE
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+       $echo "$modename: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit $EXIT_FAILURE
+      fi
+
+      dir=
+      case $file in
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+       # If there is no directory component, then add one.
+       case $file in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+       continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+       # Do a test to see if this is really a libtool program.
+       if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case $file in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+       ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+       # Export the shlibpath_var.
+       eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      if test "${save_LC_ALL+set}" = set; then
+       LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+       LANG="$save_LANG"; export LANG
+      fi
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+       eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+       $echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool clean and uninstall mode
+  clean | uninstall)
+    modename="$modename: $mode"
+    rm="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) rm="$rm $arg"; rmforce=yes ;;
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$dir" = "X$file"; then
+       dir=.
+       objdir="$origobjdir"
+      else
+       objdir="$dir/$origobjdir"
+      fi
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+       case " $rmdirs " in
+         *" $objdir "*) ;;
+         *) rmdirs="$rmdirs $objdir" ;;
+       esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if (test -L "$file") >/dev/null 2>&1 \
+       || (test -h "$file") >/dev/null 2>&1 \
+       || test -f "$file"; then
+       :
+      elif test -d "$file"; then
+       exit_status=1
+       continue
+      elif test "$rmforce" = yes; then
+       continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+       # Possibly a libtool archive, so verify it.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         . $dir/$name
+
+         # Delete the libtool libraries and symlinks.
+         for n in $library_names; do
+           rmfiles="$rmfiles $objdir/$n"
+         done
+         test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+         test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+
+         if test "$mode" = uninstall; then
+           if test -n "$library_names"; then
+             # Do each command in the postuninstall commands.
+             cmds=$postuninstall_cmds
+             save_ifs="$IFS"; IFS='~'
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd"
+               if test "$?" -ne 0 && test "$rmforce" != yes; then
+                 exit_status=1
+               fi
+             done
+             IFS="$save_ifs"
+           fi
+
+           if test -n "$old_library"; then
+             # Do each command in the old_postuninstall commands.
+             cmds=$old_postuninstall_cmds
+             save_ifs="$IFS"; IFS='~'
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd"
+               if test "$?" -ne 0 && test "$rmforce" != yes; then
+                 exit_status=1
+               fi
+             done
+             IFS="$save_ifs"
+           fi
+           # FIXME: should reinstall the best remaining shared library.
+         fi
+       fi
+       ;;
+
+      *.lo)
+       # Possibly a libtool object, so verify it.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+         # Read the .lo file
+         . $dir/$name
+
+         # Add PIC object to the list of files to remove.
+         if test -n "$pic_object" \
+            && test "$pic_object" != none; then
+           rmfiles="$rmfiles $dir/$pic_object"
+         fi
+
+         # Add non-PIC object to the list of files to remove.
+         if test -n "$non_pic_object" \
+            && test "$non_pic_object" != none; then
+           rmfiles="$rmfiles $dir/$non_pic_object"
+         fi
+       fi
+       ;;
+
+      *)
+       if test "$mode" = clean ; then
+         noexename=$name
+         case $file in
+         *.exe)
+           file=`$echo $file|${SED} 's,.exe$,,'`
+           noexename=`$echo $name|${SED} 's,.exe$,,'`
+           # $file with .exe has already been added to rmfiles,
+           # add $file without .exe
+           rmfiles="$rmfiles $file"
+           ;;
+         esac
+         # Do a test to see if this is a libtool program.
+         if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+           relink_command=
+           . $dir/$noexename
+
+           # note $name still contains .exe if it was in $file originally
+           # as does the version of $file that was added into $rmfiles
+           rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+           if test "$fast_install" = yes && test -n "$relink_command"; then
+             rmfiles="$rmfiles $objdir/lt-$name"
+           fi
+           if test "X$noexename" != "X$name" ; then
+             rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+           fi
+         fi
+       fi
+       ;;
+      esac
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles || exit_status=1
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+       $show "rmdir $dir"
+       $run rmdir $dir >/dev/null 2>&1
+      fi
+    done
+
+    exit $exit_status
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+  esac
+
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit $EXIT_FAILURE
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --tag=TAG         use configuration variables from tag TAG
+    --version         print version information
+
+MODE must be one of the following:
+
+      clean           remove files from the build directory
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool@gnu.org>."
+  exit $EXIT_SUCCESS
+  ;;
+
+clean)
+  $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                   try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                   try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                   specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+  ;;
+esac
+
+$echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit $EXIT_SUCCESS
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/config/missing b/config/missing
new file mode 100755 (executable)
index 0000000..e7ef83a
--- /dev/null
@@ -0,0 +1,360 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2003-09-02.23
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f y.tab.h ]; then
+       echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+       file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+       case "$firstarg" in
+       *o*)
+           firstarg=`echo "$firstarg" | sed s/o//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+       case "$firstarg" in
+       *h*)
+           firstarg=`echo "$firstarg" | sed s/h//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/config/mkinstalldirs b/config/mkinstalldirs
new file mode 100755 (executable)
index 0000000..6fbe5e1
--- /dev/null
@@ -0,0 +1,150 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2004-02-15.20
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit 0
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit 0
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+       errstatus=$lasterr
+      else
+       if test ! -z "$dirmode"; then
+         echo "chmod $dirmode $pathcomp"
+         lasterr=""
+         chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+         if test ! -z "$lasterr"; then
+           errstatus=$lasterr
+         fi
+       fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..a35cca4
--- /dev/null
+++ b/configure
@@ -0,0 +1,51153 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+        test "X$echo_testing_string" = "X$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+         then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+tagnames=${tagnames+${tagnames},}CXX
+
+tagnames=${tagnames+${tagnames},}F77
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="common-src/amanda.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# 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 AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot SNAPSHOT_STAMP VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_COMMENT VERSION_SUFFIX 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 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 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 LTLIBOBJS LTALLOCA'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+             localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$0" : 'X\(//\)[^/]' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CXXCPP_set=${CXXCPP+set}
+ac_env_CXXCPP_value=$CXXCPP
+ac_cv_env_CXXCPP_set=${CXXCPP+set}
+ac_cv_env_CXXCPP_value=$CXXCPP
+ac_env_F77_set=${F77+set}
+ac_env_F77_value=$F77
+ac_cv_env_F77_set=${F77+set}
+ac_cv_env_F77_value=$F77
+ac_env_FFLAGS_set=${FFLAGS+set}
+ac_env_FFLAGS_value=$FFLAGS
+ac_cv_env_FFLAGS_set=${FFLAGS+set}
+ac_cv_env_FFLAGS_value=$FFLAGS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                         [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                         [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-shared[=PKGS]
+                          build shared libraries [default=yes]
+  --enable-static[=PKGS]
+                          build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-includes=DIR    site header files for readline, etc in DIR
+  --with-libraries=DIR   site library directories for readline, etc in DIR
+  --with-configdir=DIR   runtime config files in DIR sysconfdir/amanda
+  --with-indexdir        deprecated, use indexdir in amanda.conf
+  --with-dbdir           deprecated, use infofile in amanda.conf
+  --with-logdir          deprecated, use logfile in amanda.conf
+  --with-suffixes        install binaries with version string appended to name
+  --with-client-only     deprecated, use --without-server
+  --with-server-only     deprecated, use --without-client
+  --without-client       do not build client stuff
+  --without-server       do not build server stuff (set --without-restore)
+  --without-restore      do not build amrestore nor amidxtaped
+  --without-amrecover    do not build amrecover
+  --with-index-server=HOST default amanda index server `uname -n`
+  --without-force-uid    do not force the uid to --with-user
+  --with-user=USER       force execution to USER on client systems required
+  --with-group=GROUP     group allowed to execute setuid-root programs required
+  --with-owner=USER       force ownership of files to USER default == --with-user value
+  --with-rundump         use rundump (setuid-root) to invoke dump
+  --with-config=CONFIG   default configuration DailySet1
+  --with-tape-server=HOST default restoring tape server is HOST same as --with-index-server
+  --with-tape-device=ARG restoring tape server HOST's no rewinding tape drive
+  --with-ftape-rawdevice=ARG raw device on tape server HOST's if using Linux ftape >=3.04d
+  --with-rew-tape        deprecated, use --with-tape-device
+  --with-norew-tape=ARG  deprecated, use --with-tape-device
+  --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
+  --with-gnutar=PROG     use PROG as GNU tar executable default: looks for one
+   --with-qde                use quick-and-dirty estimates for gnutar
+  --with-smbclient=PROG   use PROG as Samba's smbclient executable default: looks for one
+  --with-samba-user was deprecated
+  --with-gnutar-listdir=DIR  gnutar directory lists go in DIR localstatedir/amanda/gnutar-lists
+  --with-gnutar-listed-incremental was deprecated, use --with-gnutar-listdir
+  --without-bsd-security do not use BSD rsh/rlogin style security
+  --without-amandahosts  use .rhosts instead of .amandahosts
+  --with-krb4-security=DIR   Location of Kerberos software /usr/kerberos /usr/cygnus /usr /opt/kerberos
+    --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"
+    --with-client-principal=ARG    client host principal  "rcmd"
+    --with-client-instance=ARG     client host instance   HOSTNAME_INSTANCE
+    --with-client-keyfile=ARG      client host key file   KEYFILE
+    --with-ticket-lifetime=ARG     ticket lifetime        128
+  --with-portrange=low,high     bind unreserved TCP server sockets to ports within this range unlimited
+  --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
+  --with-db={text,db,dbm,gdbm,ndbm} use the selected database format text
+  --with-mmap            force use of mmap instead of shared memory support
+  --with-buffered-dump   buffer the dumping sockets on the server for speed
+  --with-assertions      compile assertions into code
+  --with-tmpdir=/temp/dir area Amanda can use for temp files /tmp/amanda
+  --without-debugging=/debug/dir do not record runtime debugging information in specified directory --with-tmpdir
+  --with-debug-days=NN    number of days to keep debugging files default=4
+  --with-testing=suffix use alternate service names
+  --with-dump-honor-nodump  if dump supports -h, use it for level0s too
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-tags[=TAGS]
+                          include additional configurations [automatic]
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  F77         Fortran 77 compiler command
+  FFLAGS      Fortran 77 compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+          test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+       ac_must_keep_next=false # Got value, back to normal.
+      else
+       case $ac_arg in
+         *=* | --config-cache | -C | -disable-* | --disable-* \
+         | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+         | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+         | -with-* | --with-* | -without-* | --without-* | --x)
+           case "$ac_configure_args0 " in
+             "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+           esac
+           ;;
+         -* ) ac_must_keep_next=true ;;
+       esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+       "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+       echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+              sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+       { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+       { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+       { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+       ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in config $srcdir/config; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config $srcdir/config" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in config $srcdir/config" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+
+CONFIGURE_COMMAND="'$0'"
+for arg in "$@"; do
+  CONFIGURE_COMMAND="$CONFIGURE_COMMAND '$arg'"
+done
+
+cat >>confdefs.h <<_ACEOF
+#define CONFIGURE_COMMAND "$CONFIGURE_COMMAND"
+_ACEOF
+
+
+
+am__api_version="1.8"
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+       if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+         if test $ac_prog = install &&
+           grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         elif test $ac_prog = install &&
+           grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+           # program-specific install script used by HP pwplus--don't use.
+           :
+         else
+           ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+           break 3
+         fi
+       fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # Keeping the `.' argument allows $(mkdir_p) to be used without
+  # argument.  Indeed, we sometimes output rules like
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.
+  # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+  # expensive solution, as it forces Make to start a sub-shell.)
+  mkdir_p='mkdir -p -- .'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+
+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 whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=amanda
+ VERSION=2.4.4p3
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+
+
+
+          ac_config_headers="$ac_config_headers config/config.h"
+
+
+
+if test -f "$srcdir/SNAPSHOT"; then
+  cat < "$srcdir/SNAPSHOT"
+
+  snapdate=`sed -n '/^Snapshot Date: \([0-9]*\)/ s//\1/p' < $srcdir/SNAPSHOT`
+
+  test -z "$snapdate" || VERSION="$VERSION-$snapdate"
+  SNAPSHOT_STAMP=SNAPSHOT
+else
+  SNAPSHOT_STAMP=
+fi
+
+
+if test -f config.local; then
+    echo "running local script ./config.local"
+    . ./config.local
+fi
+
+
+VERSION_MAJOR=`expr "$VERSION" : '\([0-9]*\)'`
+VERSION_MINOR=`expr "$VERSION" : '[0-9]*\.\([0-9]*\)'`
+VERSION_PATCH=`expr "$VERSION" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+VERSION_COMMENT=\"`expr "$VERSION" : '[0-9]*\.[0-9]*\.[0-9]*\(.*\)'`\"
+
+
+VERSION_SUFFIX="$VERSION"
+
+
+
+
+
+
+SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
+LOCPATH=`(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+    eval echo "$libexecdir:$PATH:/usr/local/sbin:/usr/local/bin"
+)`
+SYSLOCPATH="$SYSPATH:$LOCPATH"
+LOCSYSPATH="$LOCPATH:$SYSPATH"
+
+
+# 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"
+
+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-libraries or --without-libraries was given.
+if test "${with_libraries+set}" = set; then
+  withval="$with_libraries"
+
+       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"
+
+fi;
+
+if test "$LIBRARY_DIRS"; then
+       for dir in $LIBRARY_DIRS; do
+           if test -d "$dir"; then
+               case "$target" in
+                 *-solaris2*)
+                       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-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
+
+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"
+)`
+
+cat >>confdefs.h <<_ACEOF
+#define CONFIG_DIR "$CONFIG_DIR"
+_ACEOF
+
+
+
+
+# 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;
+
+
+# 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;
+
+
+# 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; }; }
+
+fi;
+
+
+# Check whether --with-suffixes or --without-suffixes was given.
+if test "${with_suffixes+set}" = set; then
+  withval="$with_suffixes"
+  USE_VERSION_SUFFIXES=$withval
+else
+  : ${USE_VERSION_SUFFIXES=no}
+
+fi;
+case "$USE_VERSION_SUFFIXES" in
+y | ye | yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_VERSION_SUFFIXES 1
+_ACEOF
+
+
+    program_suffix="-$VERSION"
+    # This is from the output of configure.in.
+    if test "$program_transform_name" = s,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 "$program_prefix" != NONE &&
+       program_transform_name="s,^,${program_prefix},; $program_transform_name"
+    # Use a double $ so make ignores it.
+    test "$program_suffix" != NONE &&
+       program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+    # sed with no file args requires a program.
+    test "$program_transform_name" = "" && program_transform_name="s,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;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+
+
+case "$target" in
+    *-hp-*)
+       CLIENT_SCRIPTS_OPT=amhpfixdevs
+       ;;
+    *-sni-sysv4)
+       CLIENT_SCRIPTS_OPT=amsinixfixdevs
+       ;;
+    *)
+       CLIENT_SCRIPTS_OPT=
+       ;;
+esac
+
+
+
+
+# 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; }; }
+
+fi;
+
+# 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;
+
+
+# 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) 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
+
+
+fi;
+
+
+# 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) 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
+
+
+fi;
+
+
+# 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) 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
+
+
+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
+
+
+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
+
+else
+  : ${DEFAULT_SERVER=`uname -n`}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_SERVER "$DEFAULT_SERVER"
+_ACEOF
+
+
+
+
+# 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
+  : ${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"
+
+       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
+
+
+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-group or --without-group was given.
+if test "${with_group+set}" = set; then
+  withval="$with_group"
+
+       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; }; }
+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
+
+
+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-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
+
+else
+  : ${DEFAULT_CONFIG=DailySet1}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_CONFIG "$DEFAULT_CONFIG"
+_ACEOF
+
+
+
+
+# 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
+
+else
+  : ${DEFAULT_TAPE_SERVER=$DEFAULT_SERVER}
+
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_TAPE_SERVER "$DEFAULT_TAPE_SERVER"
+_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
+
+else
+
+       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=/dev/null
+           nr_tape_dev=/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
+
+
+fi;
+
+if test -z "$DEFAULT_TAPE_DEVICE"; then
+    DEFAULT_TAPE_DEVICE=/dev/null
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_TAPE_DEVICE "$DEFAULT_TAPE_DEVICE"
+_ACEOF
+
+
+
+
+# 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
+
+else
+
+       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
+
+
+fi;
+
+if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
+    DEFAULT_RAW_TAPE_DEVICE=/dev/null
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_RAW_TAPE_DEVICE "$DEFAULT_RAW_TAPE_DEVICE"
+_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
+
+else
+
+       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
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_CHANGER_DEVICE "$DEFAULT_CHANGER_DEVICE"
+_ACEOF
+
+
+
+
+# Check whether --with-fqdn or --without-fqdn was given.
+if test "${with_fqdn+set}" = set; then
+  withval="$with_fqdn"
+  USE_FQDN=$withval
+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: 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
+
+
+# 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
+  : ${HAVE_BROKEN_FSF=no}
+
+fi;
+case "$HAVE_BROKEN_FSF" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BROKEN_FSF 1
+_ACEOF
+
+  ;;
+*) { { 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
+
+
+# Check whether --with-gnutar or --without-gnutar was given.
+if test "${with_gnutar+set}" = set; then
+  withval="$with_gnutar"
+
+       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
+
+
+fi;
+
+
+# Check whether --with-qde or --without-qde was given.
+if test "${with_qde+set}" = set; then
+  withval="$with_qde"
+  USE_QUICK_AND_DIRTY_ESTIMATES=$withval
+else
+  : ${USE_QUICK_AND_DIRTY_ESTIMATES=no}
+
+fi;
+case "$USE_QUICK_AND_DIRTY_ESTIMATES" in
+n | no) : USE_QUICK_AND_DIRTY_ESTIMATES=no;;
+y |  ye | yes) : USE_QUICK_AND_DIRTY_ESTIMATES=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_QUICK_AND_DIRTY_ESTIMATES 1
+_ACEOF
+
+  ;;
+*) { { echo "$as_me:$LINENO: error: *** You must not supply an argument to --with-qde option." >&5
+echo "$as_me: error: *** You must not supply an argument to --with-qde option." >&2;}
+   { (exit 1); exit 1; }; }
+  ;;
+esac
+
+
+
+# Check whether --with-smbclient or --without-smbclient was given.
+if test "${with_smbclient+set}" = set; then
+  withval="$with_smbclient"
+
+       case "$withval" in
+           /*) SAMBA_CLIENT="$withval";;
+           y|ye|yes) :;;
+           n|no) SAMBA_CLIENT="no";;
+           *)  { { 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
+
+
+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"
+
+       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
+  : ${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
+
+    GNUTAR_LISTED_INCREMENTAL_DIRX=$GNUTAR_LISTDIR
+else
+    GNUTAR_LISTED_INCREMENTAL_DIRX=
+fi
+
+
+
+# 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;
+
+
+# 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}
+
+fi;
+case "$BSD_SECURITY" in
+n | no) : ;;
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define BSD_SECURITY 1
+_ACEOF
+
+  ;;
+*) { { 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
+
+
+# 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;}
+   { (exit 1); exit 1; }; }
+  ;;
+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 "${KRB4_SECURITY}" = yes -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
+           if test -f ${dir}/lib/libroken.a ; then
+               KRB4LIBS="$KRB4LIBS -lroken"
+           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
+       elif test -f ${dir}/lib/libkrb4.dylib &&
+            test -f ${dir}/lib/libcrypto.dylib &&
+            test -f ${dir}/lib/libdes425.dylib ; then
+           #
+           # This is Kerberos 5 with Kerberos 4 back-support for Mac OS X.
+           #
+           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.dylib &&
+               test -f ${dir}/lib/libcom_err.dylib; then
+               KRB4LIBS="-lkrb4 -lkrb5 -lcrypto -ldes425 -lcom_err"
+           else
+               KRB4LIBS="-lkrb4 -lcrypto -ldes425"
+           fi
+           break
+       fi
+    done
+
+    if test "$KRB4LDFLAGS" = "" ; then
+       { { echo "$as_me:$LINENO: error: *** Kerberos IV not found." >&5
+echo "$as_me: error: *** Kerberos IV not found." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+else
+    echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+# 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 "$CLIENT_HOST_KEY_FILE" != "KEYFILE"; 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
+
+
+
+
+# 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"
+
+       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
+
+
+# Check whether --with-udpportrange or --without-udpportrange was given.
+if test "${with_udpportrange+set}" = set; then
+  withval="$with_udpportrange"
+
+       UDPPORTRANGE="$withval"
+
+
+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;}
+   { (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
+
+
+# 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;
+
+
+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
+
+
+# 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
+_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
+
+  ;;
+*) { { 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
+
+
+# Check whether --with-tmpdir or --without-tmpdir was given.
+if test "${with_tmpdir+set}" = set; then
+  withval="$with_tmpdir"
+  tmpdir="$withval"
+else
+  : ${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
+
+)
+
+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
+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 "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
+
+  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.
+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
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+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
+
+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
+
+    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
+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
+
+
+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; }; }
+
+# 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.  */
+
+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
+
+{ { 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 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
+
+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
+
+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
+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 ()
+{
+
+  ;
+  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
+
+{ { 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; }; }
+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
+
+  ;
+  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
+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 ()
+{
+
+  ;
+  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
+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;
+}
+
+/* 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
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+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
+
+# 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
+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
+
+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"
+
+
+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
+# 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
+
+
+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
+
+
+if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+
+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
+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
+
+  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
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+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
+
+
+
+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
+
+
+
+
+
+DUMP_PROGRAMS="ufsdump dump backup"
+GETCONF_LFS="LFS"
+
+dump_returns_1=
+xenix_tapeio=
+case "$target" in
+    *-dec-osf*)
+
+cat >>confdefs.h <<\_ACEOF
+#define STATFS_OSF1 1
+_ACEOF
+
+                       ;;
+    *-dg-*)
+                       DUMP_PROGRAMS="dump "$DUMP_PROGRAMS
+                       : ${USE_RUNDUMP=yes}
+                       dump_returns_1=yes
+                       ;;
+    *-netbsd*)
+                       ;;
+    *-freebsd*)
+                       ;;
+    *-openbsd*)
+                       ;;
+    *-hp-*)
+                       MT_FILE_FLAG="-t"
+                       GETCONF_LFS="XBS5_ILP32_OFFBIG"
+                       case "$CC" in
+                           *gcc*)
+                               AMANDA_CPPFLAGS="-D__STDC_EXT__ $AMANDA_CPPFLAGS"
+                               ;;
+                           *cc*)
+                               AMANDA_CFLAGS="-Ae $AMANDA_CFLAGS"
+                               ;;
+                       esac
+                       ;;
+  *-ibm-aix*)
+                       GETCONF_LFS="XBS5_ILP32_OFFBIG"
+                       DUMP_PROGRAMS="backup "$DUMP_PROGRAMS
+
+cat >>confdefs.h <<\_ACEOF
+#define AIX_TAPEIO 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define AIX_BACKUP 1
+_ACEOF
+
+                       ;;
+  m88k-motorola-sysv4)
+                       ;;
+  *-nextstep3)
+                       ;;
+  *-pc-bsdi*)
+                       ;;
+  *-pc-linux-*)
+                       ;;
+  alpha*-*-linux-*)
+                       ;;
+  sparc*-*-linux-*)
+                       ;;
+  powerpc-*-linux-*)
+                       ;;
+  *-sgi-irix3*)
+                                               CC=gcc
+                       ;;
+  *-sgi-irix4*)
+                       ;;
+  *-sgi-irix5*)
+                       ;;
+  *-sgi-irix6*)
+                       ;;
+  *-solaris2*)
+                       ;;
+  *-sun-sunos4.1*)
+                       ;;
+  *-ultrix*)
+                       : ${USE_RUNDUMP=yes}
+
+cat >>confdefs.h <<\_ACEOF
+#define STATFS_ULTRIX 1
+_ACEOF
+
+                       dump_returns_1=yes
+                       ;;
+  *-sysv4.2uw2*)
+
+cat >>confdefs.h <<\_ACEOF
+#define UWARE_TAPEIO 1
+_ACEOF
+
+                       ;;
+  *-sco3.2v4*)
+                       DEV_PREFIX=/dev/
+                       RDEV_PREFIX=/dev/
+                       ;;
+  *-sco3.2v5*)
+                       xenix_tapeio=yes
+
+cat >>confdefs.h <<\_ACEOF
+#define STATFS_SCO_OS5 1
+_ACEOF
+
+                       ;;
+  i386-pc-isc4*)
+                       xenix_tapeio=yes
+                       ;;
+  *-sni-sysv4)
+                       ;;
+  *-pc-cygwin)
+
+cat >>confdefs.h <<\_ACEOF
+#define IGNORE_TAR_ERRORS 1
+_ACEOF
+
+                       # Cygwin needs PATH to find cygwin1.dll
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_PATH_ENV 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define IGNORE_UID_CHECK 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define IGNORE_FSTAB 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define DONT_SUID_ROOT 1
+_ACEOF
+
+                       NEED_SETUID_CLIENT=false
+                       NEED_RUNTIME_PSEUDO_RELOC=true
+                       ;;
+  *)
+                       cat <<END
+
+*****
+This machine, target type $target, is not known
+to be fully supported by this configure script.  If the
+installation of Amanda on this system succeeds or needed
+any patches, please email amanda-hackers@amanda.org with
+the patches or an indication of the sucess or failure of
+the Amanda installation on your system.
+*****
+
+END
+               ;;
+esac
+
+if test -n "$dump_returns_1"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define DUMP_RETURNS_1 1
+_ACEOF
+
+fi
+
+if test -n "$xenix_tapeio"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define XENIX_TAPEIO 1
+_ACEOF
+
+fi
+
+AMANDA_CFLAGS="$AMANDA_CFLAGS $KRB4INCLUDES"
+AMANDA_CPPFLAGS="$AMANDA_CPPFLAGS $KRB4INCLUDES"
+AMANDA_LDFLAGS="$AMANDA_LDFLAGS $KRB4LDFLAGS"
+AMANDA_LIBS="$KRB4LIBS $AMANDA_LIBS"
+CFLAGS="$CFLAGS $AMANDA_CFLAGS"
+CPPFLAGS="$CPPFLAGS $AMANDA_CPPFLAGS"
+LDFLAGS="$LDFLAGS $AMANDA_LDFLAGS"
+LIBS="$AMANDA_LIBS $LIBS"
+
+
+: ${MT_FILE_FLAG="-f"}
+
+
+cat >>confdefs.h <<_ACEOF
+#define MT_FILE_FLAG "$MT_FILE_FLAG"
+_ACEOF
+
+
+
+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
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+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
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+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 $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 <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+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_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (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
+  :
+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 )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+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_header>
+_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
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# ------ AX CREATE STDINT H -------------------------------------
+echo "$as_me:$LINENO: checking for stdint types" >&5
+echo $ECHO_N "checking for stdint types... $ECHO_C" >&6
+ac_stdint_h=`echo common-src/amanda-int.h`
+# try to shortcircuit - if the default include path of the compiler
+# can find a "stdint.h" header then we assume that all compilers can.
+if test "${ac_cv_header_stdint_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS=""
+old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS=""
+old_CFLAGS="$CFLAGS"     ; CFLAGS=""
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdint.h>
+int
+main ()
+{
+int_least32_t v = 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_stdint_result="(assuming C99 compatible system)"
+ ac_cv_header_stdint_t="stdint.h";
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdint_t=""
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+CXXFLAGS="$old_CXXFLAGS"
+CPPFLAGS="$old_CPPFLAGS"
+CFLAGS="$old_CFLAGS"
+fi
+
+
+v="... $ac_cv_header_stdint_h"
+if test "$ac_stdint_h" = "stdint.h" ; then
+ echo "$as_me:$LINENO: result: (are you sure you want them in ./stdint.h?)" >&5
+echo "${ECHO_T}(are you sure you want them in ./stdint.h?)" >&6
+elif test "$ac_stdint_h" = "inttypes.h" ; then
+ echo "$as_me:$LINENO: result: (are you sure you want them in ./inttypes.h?)" >&5
+echo "${ECHO_T}(are you sure you want them in ./inttypes.h?)" >&6
+elif test "_$ac_cv_header_stdint_t" = "_" ; then
+ echo "$as_me:$LINENO: result: (putting them into $ac_stdint_h)$v" >&5
+echo "${ECHO_T}(putting them into $ac_stdint_h)$v" >&6
+else
+ ac_cv_header_stdint="$ac_cv_header_stdint_t"
+ echo "$as_me:$LINENO: result: $ac_cv_header_stdint (shortcircuit)" >&5
+echo "${ECHO_T}$ac_cv_header_stdint (shortcircuit)" >&6
+fi
+
+if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit..
+
+
+inttype_headers=`echo  | sed -e 's/,/ /g'`
+
+ac_cv_stdint_result="(no helpful system typedefs seen)"
+echo "$as_me:$LINENO: checking for stdint uintptr_t" >&5
+echo $ECHO_N "checking for stdint uintptr_t... $ECHO_C" >&6
+if test "${ac_cv_header_stdint_x+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h)
+  echo "$as_me:$LINENO: result: (..)" >&5
+echo "${ECHO_T}(..)" >&6
+  for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_uintptr_t
+   unset ac_cv_type_uint64_t
+   echo "$as_me:$LINENO: checking for uintptr_t" >&5
+echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6
+if test "${ac_cv_type_uintptr_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 <$i>
+
+int
+main ()
+{
+if ((uintptr_t *) 0)
+  return 0;
+if (sizeof (uintptr_t))
+  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_uintptr_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uintptr_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5
+echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6
+if test $ac_cv_type_uintptr_t = yes; then
+  ac_cv_header_stdint_x=$i
+else
+       continue
+fi
+
+   echo "$as_me:$LINENO: checking for uint64_t" >&5
+echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint64_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<$i>
+
+int
+main ()
+{
+if ((uint64_t *) 0)
+  return 0;
+if (sizeof (uint64_t))
+  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_uint64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint64_t" >&6
+if test $ac_cv_type_uint64_t = yes; then
+  and64="/uint64_t"
+else
+  and64=""
+fi
+
+   ac_cv_stdint_result="(seen uintptr_t$and64 in $i)"
+   break;
+  done
+  echo "$as_me:$LINENO: checking for stdint uintptr_t" >&5
+echo $ECHO_N "checking for stdint uintptr_t... $ECHO_C" >&6
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdint_x" >&5
+echo "${ECHO_T}$ac_cv_header_stdint_x" >&6
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+echo "$as_me:$LINENO: checking for stdint uint32_t" >&5
+echo $ECHO_N "checking for stdint uint32_t... $ECHO_C" >&6
+if test "${ac_cv_header_stdint_o+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h)
+  echo "$as_me:$LINENO: result: (..)" >&5
+echo "${ECHO_T}(..)" >&6
+  for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do
+   unset ac_cv_type_uint32_t
+   unset ac_cv_type_uint64_t
+   echo "$as_me:$LINENO: checking for uint32_t" >&5
+echo $ECHO_N "checking for uint32_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint32_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 <$i>
+
+int
+main ()
+{
+if ((uint32_t *) 0)
+  return 0;
+if (sizeof (uint32_t))
+  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_uint32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint32_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint32_t" >&6
+if test $ac_cv_type_uint32_t = yes; then
+  ac_cv_header_stdint_o=$i
+else
+       continue
+fi
+
+   echo "$as_me:$LINENO: checking for uint64_t" >&5
+echo $ECHO_N "checking for uint64_t... $ECHO_C" >&6
+if test "${ac_cv_type_uint64_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<$i>
+
+int
+main ()
+{
+if ((uint64_t *) 0)
+  return 0;
+if (sizeof (uint64_t))
+  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_uint64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uint64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uint64_t" >&5
+echo "${ECHO_T}$ac_cv_type_uint64_t" >&6
+if test $ac_cv_type_uint64_t = yes; then
+  and64="/uint64_t"
+else
+  and64=""
+fi
+
+   ac_cv_stdint_result="(seen uint32_t$and64 in $i)"
+   break;
+  done
+  echo "$as_me:$LINENO: checking for stdint uint32_t" >&5
+echo $ECHO_N "checking for stdint uint32_t... $ECHO_C" >&6
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdint_o" >&5
+echo "${ECHO_T}$ac_cv_header_stdint_o" >&6
+fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+if test "_$ac_cv_header_stdint_o" = "_" ; then
+echo "$as_me:$LINENO: checking for stdint u_int32_t" >&5
+echo $ECHO_N "checking for stdint u_int32_t... $ECHO_C" >&6
+if test "${ac_cv_header_stdint_u+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h)
+  echo "$as_me:$LINENO: result: (..)" >&5
+echo "${ECHO_T}(..)" >&6
+  for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do
+   unset ac_cv_type_u_int32_t
+   unset ac_cv_type_u_int64_t
+   echo "$as_me:$LINENO: checking for u_int32_t" >&5
+echo $ECHO_N "checking for u_int32_t... $ECHO_C" >&6
+if test "${ac_cv_type_u_int32_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 <$i>
+
+int
+main ()
+{
+if ((u_int32_t *) 0)
+  return 0;
+if (sizeof (u_int32_t))
+  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_u_int32_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_u_int32_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_u_int32_t" >&5
+echo "${ECHO_T}$ac_cv_type_u_int32_t" >&6
+if test $ac_cv_type_u_int32_t = yes; then
+  ac_cv_header_stdint_u=$i
+else
+       continue
+fi
+
+   echo "$as_me:$LINENO: checking for u_int64_t" >&5
+echo $ECHO_N "checking for u_int64_t... $ECHO_C" >&6
+if test "${ac_cv_type_u_int64_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<$i>
+
+int
+main ()
+{
+if ((u_int64_t *) 0)
+  return 0;
+if (sizeof (u_int64_t))
+  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_u_int64_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_u_int64_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_u_int64_t" >&5
+echo "${ECHO_T}$ac_cv_type_u_int64_t" >&6
+if test $ac_cv_type_u_int64_t = yes; then
+  and64="/u_int64_t"
+else
+  and64=""
+fi
+
+   ac_cv_stdint_result="(seen u_int32_t$and64 in $i)"
+   break;
+  done
+  echo "$as_me:$LINENO: checking for stdint u_int32_t" >&5
+echo $ECHO_N "checking for stdint u_int32_t... $ECHO_C" >&6
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdint_u" >&5
+echo "${ECHO_T}$ac_cv_header_stdint_u" >&6
+fi fi
+
+if test "_$ac_cv_header_stdint_x" = "_" ; then
+   echo "$as_me:$LINENO: checking for stdint datatype model" >&5
+echo $ECHO_N "checking for stdint datatype model... $ECHO_C" >&6
+   echo "$as_me:$LINENO: result: (..)" >&5
+echo "${ECHO_T}(..)" >&6
+   echo "$as_me:$LINENO: checking for char" >&5
+echo $ECHO_N "checking for char... $ECHO_C" >&6
+if test "${ac_cv_type_char+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
+int
+main ()
+{
+if ((char *) 0)
+  return 0;
+if (sizeof (char))
+  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_char=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_char=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_char" >&5
+echo "${ECHO_T}$ac_cv_type_char" >&6
+
+echo "$as_me:$LINENO: checking size of char" >&5
+echo $ECHO_N "checking size of char... $ECHO_C" >&6
+if test "${ac_cv_sizeof_char+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_char" = 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 (char))) >= 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 (char))) <= $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
+
+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 (char))) < 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 (char))) >= $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 (char))) <= $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_char=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (char), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (char), 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 (char)); }
+unsigned long ulongval () { return (long) (sizeof (char)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (char))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (char))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (char))))
+       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_char=`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 (char), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (char), 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_char=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_char" >&5
+echo "${ECHO_T}$ac_cv_sizeof_char" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+_ACEOF
+
+
+   echo "$as_me:$LINENO: checking for short" >&5
+echo $ECHO_N "checking for short... $ECHO_C" >&6
+if test "${ac_cv_type_short+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
+int
+main ()
+{
+if ((short *) 0)
+  return 0;
+if (sizeof (short))
+  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_short=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_short=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5
+echo "${ECHO_T}$ac_cv_type_short" >&6
+
+echo "$as_me:$LINENO: checking size of short" >&5
+echo $ECHO_N "checking size of short... $ECHO_C" >&6
+if test "${ac_cv_sizeof_short+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_short" = 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 (short))) >= 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 (short))) <= $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
+
+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 (short))) < 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 (short))) >= $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 (short))) <= $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_short=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 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 (short)); }
+unsigned long ulongval () { return (long) (sizeof (short)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (short))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (short))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (short))))
+       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_short=`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 (short), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (short), 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_short=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5
+echo "${ECHO_T}$ac_cv_sizeof_short" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+   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
+  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
+
+ac_cv_type_int=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: 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
+  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
+
+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
+
+  ;
+  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 (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
+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 ()
+{
+
+  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);
+
+  ;
+  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_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
+
+( 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
+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_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
+
+
+   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
+  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
+
+ac_cv_type_long=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: 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
+  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
+
+  ;
+  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
+
+  ;
+  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
+
+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
+
+  ;
+  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 (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); } &&
+        { 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_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); } && { 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_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
+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 SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+   echo "$as_me:$LINENO: checking for void*" >&5
+echo $ECHO_N "checking for void*... $ECHO_C" >&6
+if test "${ac_cv_type_voidp+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
+int
+main ()
+{
+if ((void* *) 0)
+  return 0;
+if (sizeof (void*))
+  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_voidp=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_voidp=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_voidp" >&5
+echo "${ECHO_T}$ac_cv_type_voidp" >&6
+
+echo "$as_me:$LINENO: checking size of void*" >&5
+echo $ECHO_N "checking size of void*... $ECHO_C" >&6
+if test "${ac_cv_sizeof_voidp+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_voidp" = 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 (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_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 (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; 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
+
+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_stdint_char_model=""
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short"
+   ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model=""
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long"
+   ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp"
+   name="$ac_cv_stdint_long_model"
+   case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in
+    122/242)     name="$name,  IP16 (standard 16bit machine)" ;;
+    122/244)     name="$name,  LP32 (standard 32bit mac/win)" ;;
+    122/*)       name="$name        (unusual int16 model)" ;;
+    124/444)     name="$name, ILP32 (standard 32bit unixish)" ;;
+    124/488)     name="$name,  LP64 (standard 64bit unixish)" ;;
+    124/448)     name="$name, LLP64 (unusual  64bit unixish)" ;;
+    124/*)       name="$name        (unusual int32 model)" ;;
+    128/888)     name="$name, ILP64 (unusual  64bit numeric)" ;;
+    128/*)       name="$name        (unusual int64 model)" ;;
+    222/*|444/*) name="$name        (unusual dsptype)" ;;
+     *)          name="$name        (very unusal model)" ;;
+   esac
+   echo "$as_me:$LINENO: result: combined for stdint datatype model...  $name" >&5
+echo "${ECHO_T}combined for stdint datatype model...  $name" >&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.  */
+#include <$ac_cv_header_stdint>
+
+int
+main ()
+{
+if ((int_least32_t *) 0)
+  return 0;
+if (sizeof (int_least32_t))
+  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_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.  */
+#include<$ac_cv_header_stdint>
+
+int
+main ()
+{
+if ((int_fast32_t *) 0)
+  return 0;
+if (sizeof (int_fast32_t))
+  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_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.  */
+_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;
+}
+_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
+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 "$amanda_cv_awk_var_assignment" = no; 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 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
+
+  ;;
+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
+
+  test -n "$EGREP" && 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:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  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
+
+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
+
+  ;;
+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
+
+  test -n "$GREP" && break
+done
+
+if test -z "$GREP"; then
+    GREP=grep
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define GREP "$GREP"
+_ACEOF
+
+
+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
+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
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$GNUTAR" && 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
+
+if test "x$SAMBA_CLIENT" != "xno"
+then 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
+  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
+
+  test -n "$SAMBA_CLIENT" && break
+done
+
+else SAMBA_CLIENT=
+fi
+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 SAMBA_CLIENT "$SAMBA_CLIENT"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define SAMBA_VERSION $smbversion
+_ACEOF
+
+  fi
+
+fi
+
+
+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
+  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
+
+if test -n "$GZIP"; then
+  echo "$as_me:$LINENO: result: $GZIP" >&5
+echo "${ECHO_T}$GZIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$GZIP" && 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
+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
+  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
+
+  ;;
+esac
+fi
+MAILER=$ac_cv_path_MAILER
+
+if test -n "$MAILER"; then
+  echo "$as_me:$LINENO: result: $MAILER" >&5
+echo "${ECHO_T}$MAILER" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$MAILER" && 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
+
+cat >>confdefs.h <<_ACEOF
+#define MAILER "$MAILER"
+_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
+
+  ;;
+esac
+fi
+MT=$ac_cv_path_MT
+
+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 "$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
+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
+
+  ;;
+esac
+fi
+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 "$CHIO" && break
+done
+test -n "$CHIO" || CHIO="chio"
+
+
+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
+
+  ;;
+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
+
+  test -n "$CHS" && break
+done
+test -n "$CHS" || CHS="chs"
+
+
+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
+
+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_path_MCUTIL+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
+
+  ;;
+esac
+fi
+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 "$MCUTIL" && break
+done
+test -n "$MCUTIL" || MCUTIL="mcutil"
+
+
+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
+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
+
+  ;;
+esac
+fi
+PRINT=$ac_cv_path_PRINT
+
+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 "$PRINT" && break
+done
+
+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
+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_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
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  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 $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
+
+  ;;
+esac
+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
+fi
+
+  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 $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
+
+  test -n "$DUMP" && break
+done
+
+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
+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
+
+  ;;
+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 "$amanda_cv_dump_estimate" != no; 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
+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 "$amanda_cv_honor_nodump" = yes; 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
+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
+
+  ;;
+esac
+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
+fi
+
+  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 $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"
+_ACEOF
+
+
+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_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
+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
+
+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 "$VXRESTORE" && break
+done
+
+if test "$VXDUMP" -a "$VXRESTORE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define VXDUMP "$VXDUMP"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VXRESTORE "$VXRESTORE"
+_ACEOF
+
+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
+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
+
+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 "$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
+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
+
+  ;;
+esac
+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
+fi
+
+  test -n "$VRESTORE" && break
+done
+
+if test "$VDUMP" -a "$VRESTORE"; then
+
+cat >>confdefs.h <<_ACEOF
+#define VDUMP "$VDUMP"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VRESTORE "$VRESTORE"
+_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"
+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
+
+
+
+
+
+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
+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
+
+
+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 "$need_resetofs" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_RESETOFS 1
+_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"
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_shared=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi;
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_static=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi;
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_fast_install=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi;
+
+echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6
+if test "${lt_cv_path_SED+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && break
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+SED=$lt_cv_path_SED
+
+fi
+
+echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+if test "${lt_cv_path_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm="$ac_dir/${ac_tool_prefix}nm"
+    if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+      */dev/null* | *'Invalid file or object type'*)
+       lt_cv_path_NM="$tmp_nm -B"
+       break
+        ;;
+      *)
+       case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+       */dev/null*)
+         lt_cv_path_NM="$tmp_nm -p"
+         break
+         ;;
+       *)
+         lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+         ;;
+       esac
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+echo "${ECHO_T}$lt_cv_path_NM" >&6
+NM="$lt_cv_path_NM"
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
+echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case "$host_cpu" in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  case $host_cpu in
+  alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*)
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  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
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 10641 "configure"' > conftest.$ac_ext
+  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
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  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
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  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
+
+     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
+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
+  lt_cv_cc_needs_belf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+lt_cv_cc_needs_belf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext 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
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+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_header>
+_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_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  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_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+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_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# 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); }
+
+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_cxx_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
+
+  ;
+  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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_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.  */
+
+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_cxx_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_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+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_cxx_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_cxx_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
+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
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  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_CXX_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+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
+
+  am_cv_CXX_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_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+  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_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$F77"; then
+  ac_cv_prog_F77="$F77" # 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_F77="$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
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+  echo "$as_me:$LINENO: result: $F77" >&5
+echo "${ECHO_T}$F77" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$F77" && break
+  done
+fi
+if test -z "$F77"; then
+  ac_ct_F77=$F77
+  for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+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_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_F77"; then
+  ac_cv_prog_ac_ct_F77="$ac_ct_F77" # 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_F77="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+  echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
+echo "${ECHO_T}$ac_ct_F77" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_F77" && break
+done
+
+  F77=$ac_ct_F77
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:11740:" \
+     "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
+  (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); }
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.  (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+      program main
+#ifndef __GNUC__
+       choke me
+#endif
+
+      end
+_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_f77_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_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
+echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_f77_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  FFLAGS=-g
+cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_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_f77_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_f77_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_f77_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
+echo "${ECHO_T}$ac_cv_prog_f77_g" >&6
+if test "$ac_test_FFLAGS" = set; then
+  FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+
+G77=`test $ac_compiler_gnu = yes && echo yes`
+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
+
+
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# find the maximum length of command line arguments
+echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
+echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+ *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    while (test "X"`$CONFIG_SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
+              = "XX$teststring") >/dev/null 2>&1 &&
+           new_result=`expr "X$teststring" : ".*" 2>&1` &&
+           lt_cv_sys_max_cmd_len=$new_result &&
+           test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
+echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6
+else
+  echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+fi
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
+echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris* | sysv5*)
+  symcode='[BDRT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[      ]\($symcode$symcode*\)[         ][      ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  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
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+       if grep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+         cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+         cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$ac_objext conftstm.$ac_objext
+         lt_save_LIBS="$LIBS"
+         lt_save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$ac_objext"
+         CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+         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); } && test -s conftest${ac_exeext}; then
+           pipe_works=yes
+         fi
+         LIBS="$lt_save_LIBS"
+         CFLAGS="$lt_save_CFLAGS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+else
+  echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+fi
+
+echo "$as_me:$LINENO: checking for objdir" >&5
+echo $ECHO_N "checking for objdir... $ECHO_C" >&6
+if test "${lt_cv_objdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
+echo "${ECHO_T}$lt_cv_objdir" >&6
+objdir=$lt_cv_objdir
+
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; 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_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # 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_AR="${ac_tool_prefix}ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_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
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; 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_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false"
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  AR=$ac_ct_AR
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; 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_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # 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_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; 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_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+enable_dlopen=no
+enable_win32_dll=no
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+  withval="$with_pic"
+  pic_mode="$withval"
+else
+  pic_mode=default
+fi;
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+lt_save_CC="$CC"
+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
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+#
+# Check for any special shared library compilation flags.
+#
+lt_prog_cc_shlib=
+if test "$GCC" = no; then
+  case $host_os in
+  sco3.2v5*)
+    lt_prog_cc_shlib='-belf'
+    ;;
+  esac
+fi
+if test -n "$lt_prog_cc_shlib"; then
+  { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5
+echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;}
+  if echo "$old_CC $old_CFLAGS " | grep "[     ]$lt_prog_cc_shlib[     ]" >/dev/null; then :
+  else
+    { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
+echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;}
+    lt_cv_prog_cc_can_build_shared=no
+  fi
+fi
+
+
+#
+# Check to make sure the static flag actually works.
+#
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_prog_compiler_static"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+     else
+       lt_prog_compiler_static_works=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works" >&6
+
+if test x"$lt_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:12778: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:12782: \$? = $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
+     if test ! -s conftest.err; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static='-Bstatic'
+      else
+       lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-static'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_prog_compiler_pic='-Kpic'
+      lt_prog_compiler_static='-dn'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_prog_compiler_pic='-Kconform_pic'
+       lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13011: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:13015: \$? = $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
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6
+
+if test x"$lt_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13071: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:13075: \$? = $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
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag=
+  enable_shared_with_static_runtimes=no
+  archive_cmds=
+  archive_expsym_cmds=
+  old_archive_From_new_cmds=
+  old_archive_from_expsyms_cmds=
+  export_dynamic_flag_spec=
+  whole_archive_flag_spec=
+  thread_safe_flag_spec=
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_direct=no
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  link_all_deplibs=unknown
+  hardcode_automatic=no
+  module_cmds=
+  module_expsym_cmds=
+  always_export_symbols=no
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       ld_shlibs=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       allow_undefined_flag=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       ld_shlibs=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_cmds="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        archive_expsym_cmds="$tmp_archive_cmds"
+      fi
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = yes; then
+      runpath_var=LD_RUN_PATH
+      hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+      export_dynamic_flag_spec='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       whole_archive_flag_spec=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       else
+         export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.012|aix4.012.*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         hardcode_direct=yes
+         else
+         # We have old collect2
+         hardcode_direct=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L=yes
+         hardcode_libdir_flag_spec='-L$libdir'
+         hardcode_libdir_separator=
+         fi
+       esac
+       shared_flag='-shared'
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+       if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+       fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       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
+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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+       archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+         allow_undefined_flag="-z nodefs"
+         archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        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
+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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         no_undefined_flag=' ${wl}-bernotok'
+         allow_undefined_flag=' ${wl}-berok'
+         # -bexpall does not export symbols beginning with underscore (_)
+         always_export_symbols=yes
+         # Exported symbols can be pulled into shared objects from archives
+         whole_archive_flag_spec=' '
+         archive_cmds_need_lc=yes
+         # This is similar to how AIX traditionally builds it's shared libraries.
+         archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs=no
+      ;;
+
+    bsdi4*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      archive_cmds_need_lc=no
+      case "$host_os" in
+      rhapsody* | darwin1.[012])
+       allow_undefined_flag='-undefined suppress'
+       ;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       allow_undefined_flag='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+       ;;
+      esac
+       lt_int_apple_cc_single_mod=no
+       output_verbose_link_cmd='echo'
+       if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+         lt_int_apple_cc_single_mod=yes
+       fi
+       if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+         archive_cmds='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+       else
+        archive_cmds='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      module_cmds='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      hardcode_direct=no
+      hardcode_automatic=yes
+      hardcode_shlibpath_var=unsupported
+      whole_archive_flag_spec='-all_load $convenience'
+      link_all_deplibs=yes
+    else
+      ld_shlibs=no
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       *)
+         archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*)
+         hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+         hardcode_libdir_flag_spec_ld='+b $libdir'
+         hardcode_libdir_separator=:
+         hardcode_direct=no
+         hardcode_shlibpath_var=no
+         ;;
+       ia64*)
+         hardcode_libdir_flag_spec='-L$libdir'
+         hardcode_direct=no
+         hardcode_shlibpath_var=no
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L=yes
+         ;;
+       *)
+         hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+         hardcode_libdir_separator=:
+         hardcode_direct=yes
+         export_dynamic_flag_spec='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_ld='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    openbsd*)
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec='${wl}-E'
+      else
+       case $host_os in
+        openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+          archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          hardcode_libdir_flag_spec='-R$libdir'
+          ;;
+        *)
+          archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       allow_undefined_flag=' -expect_unresolved \*'
+       archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+       allow_undefined_flag=' -expect_unresolved \*'
+       archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      hardcode_libdir_separator=:
+      ;;
+
+    sco3.2v5*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z text'
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+       whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         reload_cmds='$CC -r -o $output$reload_objs'
+         hardcode_direct=no
+        ;;
+       motorola)
+         archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_shlibpath_var=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=no
+      hardcode_shlibpath_var=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
+      no_undefined_flag='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv5*)
+      no_undefined_flag=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      hardcode_libdir_flag_spec=
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+echo "${ECHO_T}$ld_shlibs" >&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag
+        allow_undefined_flag=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc=no
+        else
+         archive_cmds_need_lc=yes
+        fi
+        allow_undefined_flag=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
+echo "${ECHO_T}$archive_cmds_need_lc" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var " || \
+   test "X$hardcode_automatic"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+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 shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); 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 shl_load
+
+/* 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 shl_load ();
+/* 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_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  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
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  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
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+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_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+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 dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); 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 dlopen
+
+/* 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 dlopen ();
+/* 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_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  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
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+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_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  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
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+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_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 15255 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 15353 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# Report which librarie types wil actually be built
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+  darwin* | rhapsody*)
+  if test "$GCC" = yes; then
+    archive_cmds_need_lc=no
+    case "$host_os" in
+    rhapsody* | darwin1.[012])
+      allow_undefined_flag='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       allow_undefined_flag='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    output_verbose_link_cmd='echo'
+    archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring'
+    module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag  -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    hardcode_direct=no
+    hardcode_automatic=yes
+    hardcode_shlibpath_var=unsupported
+    whole_archive_flag_spec='-all_load $convenience'
+    link_all_deplibs=yes
+  else
+    ld_shlibs=no
+  fi
+    ;;
+esac
+echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler \
+    CC \
+    LD \
+    lt_prog_compiler_wl \
+    lt_prog_compiler_pic \
+    lt_prog_compiler_static \
+    lt_prog_compiler_no_builtin_flag \
+    export_dynamic_flag_spec \
+    thread_safe_flag_spec \
+    whole_archive_flag_spec \
+    enable_shared_with_static_runtimes \
+    old_archive_cmds \
+    old_archive_from_new_cmds \
+    predep_objects \
+    postdep_objects \
+    predeps \
+    postdeps \
+    compiler_lib_search_path \
+    archive_cmds \
+    archive_expsym_cmds \
+    postinstall_cmds \
+    postuninstall_cmds \
+    old_archive_from_expsyms_cmds \
+    allow_undefined_flag \
+    no_undefined_flag \
+    export_symbols_cmds \
+    hardcode_libdir_flag_spec \
+    hardcode_libdir_flag_spec_ld \
+    hardcode_libdir_separator \
+    hardcode_automatic \
+    module_cmds \
+    module_expsym_cmds \
+    lt_cv_prog_compiler_c_o \
+    exclude_expsyms \
+    include_expsyms; do
+
+    case $var in
+    old_archive_cmds | \
+    old_archive_from_new_cmds | \
+    archive_cmds | \
+    archive_expsym_cmds | \
+    module_cmds | \
+    module_expsym_cmds | \
+    old_archive_from_expsyms_cmds | \
+    export_symbols_cmds | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  { echo "$as_me:$LINENO: creating $ofile" >&5
+echo "$as_me: creating $ofile" >&6;}
+
+  cat <<__EOF__ >> "$cfgfile"
+#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+
+# Check whether --with-tags or --without-tags was given.
+if test "${with_tags+set}" = set; then
+  withval="$with_tags"
+  tagnames="$withval"
+fi;
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;}
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;}
+    else
+      { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5
+echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
+    fi
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in
+    "") ;;
+    *)  { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5
+echo "$as_me: error: invalid tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+       ;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5
+echo "$as_me: error: tag name \"$tagname\" already exists" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+       if test -n "$CXX" && test "X$CXX" != "Xno"; then
+         ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_automatic_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+# Source file extension for C++ test sources.
+ac_ext=cc
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+compiler_CXX=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+else
+  lt_prog_compiler_no_builtin_flag_CXX=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+       grep 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec_CXX=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+ld_shlibs_CXX=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+       for ld_flag in $LDFLAGS; do
+         case $ld_flag in
+         *-brtl*)
+           aix_use_runtimelinking=yes
+           break
+           ;;
+         esac
+       done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    archive_cmds_CXX=''
+    hardcode_direct_CXX=yes
+    hardcode_libdir_separator_CXX=':'
+    link_all_deplibs_CXX=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.012|aix4.012.*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+       collect2name=`${CC} -print-prog-name=collect2`
+       if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+       then
+         # We have reworked collect2
+         hardcode_direct_CXX=yes
+       else
+         # We have old collect2
+         hardcode_direct_CXX=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L_CXX=yes
+         hardcode_libdir_flag_spec_CXX='-L$libdir'
+         hardcode_libdir_separator_CXX=
+       fi
+      esac
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+       shared_flag='-G'
+      else
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag='${wl}-G'
+       else
+         shared_flag='${wl}-bM:SRE'
+       fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    always_export_symbols_CXX=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      allow_undefined_flag_CXX='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      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
+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_cxx_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+      hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+       hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+       allow_undefined_flag_CXX="-z nodefs"
+       archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+       # Determine the default libpath from the value encoded in an empty executable.
+       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
+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_cxx_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+       # Warning - without using the other run time loading flags,
+       # -berok will link without error, but may produce a broken library.
+       no_undefined_flag_CXX=' ${wl}-bernotok'
+       allow_undefined_flag_CXX=' ${wl}-berok'
+       # -bexpall does not export symbols beginning with underscore (_)
+       always_export_symbols_CXX=yes
+       # Exported symbols can be pulled into shared objects from archives
+       whole_archive_flag_spec_CXX=' '
+       archive_cmds_need_lc_CXX=yes
+       # This is similar to how AIX traditionally builds it's shared libraries.
+       archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+  chorus*)
+    case $cc_basename in
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+    # as there is no search path for DLLs.
+    hardcode_libdir_flag_spec_CXX='-L$libdir'
+    allow_undefined_flag_CXX=unsupported
+    always_export_symbols_CXX=no
+    enable_shared_with_static_runtimes_CXX=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+       cp $export_symbols $output_objdir/$soname.def;
+      else
+       echo EXPORTS > $output_objdir/$soname.def;
+       cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+    else
+      ld_shlibs_CXX=no
+    fi
+  ;;
+
+  darwin* | rhapsody*)
+  if test "$GXX" = yes; then
+    archive_cmds_need_lc_CXX=no
+    case "$host_os" in
+    rhapsody* | darwin1.[012])
+      allow_undefined_flag_CXX='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       allow_undefined_flag_CXX='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag_CXX='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag_CXX='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    lt_int_apple_cc_single_mod=no
+    output_verbose_link_cmd='echo'
+    if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+      lt_int_apple_cc_single_mod=yes
+    fi
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    else
+      archive_cmds_CXX='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    fi
+    module_cmds_CXX='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    hardcode_direct_CXX=no
+    hardcode_automatic_CXX=yes
+    hardcode_shlibpath_var_CXX=unsupported
+    whole_archive_flag_spec_CXX='-all_load $convenience'
+    link_all_deplibs_CXX=yes
+  else
+    ld_shlibs_CXX=no
+  fi
+    ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      ghcx)
+       # Green Hills C++ Compiler
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  freebsd12*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    ld_shlibs_CXX=no
+    ;;
+  freebsd-elf*)
+    archive_cmds_need_lc_CXX=no
+    ;;
+  freebsd* | kfreebsd*-gnu)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    ld_shlibs_CXX=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    export_dynamic_flag_spec_CXX='${wl}-E'
+    hardcode_direct_CXX=yes
+    hardcode_minus_L_CXX=yes # Not in the search PATH,
+                               # but as the default
+                               # location of the library.
+
+    case $cc_basename in
+    CC)
+      # FIXME: insert proper C++ library support
+      ld_shlibs_CXX=no
+      ;;
+    aCC)
+      archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      case "$host_cpu" in
+      hppa*64*)
+       hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+       hardcode_libdir_flag_spec_ld_CXX='+b $libdir'
+       hardcode_libdir_separator_CXX=:
+        ;;
+      ia64*)
+       hardcode_libdir_flag_spec_CXX='-L$libdir'
+        ;;
+      *)
+       hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator_CXX=:
+       export_dynamic_flag_spec_CXX='${wl}-E'
+        ;;
+      esac
+    fi
+    case "$host_cpu" in
+    hppa*64*)
+      hardcode_direct_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      ;;
+    ia64*)
+      hardcode_direct_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      hardcode_minus_L_CXX=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    *)
+      hardcode_direct_CXX=yes
+      hardcode_minus_L_CXX=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      aCC)
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+         ;;
+       *)
+         archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       esac
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test $with_gnu_ld = no; then
+           case "$host_cpu" in
+           ia64*|hppa*64*)
+             archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+             ;;
+           *)
+             archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           esac
+         fi
+       else
+         # FIXME: insert proper C++ library support
+         ld_shlibs_CXX=no
+       fi
+       ;;
+    esac
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC)
+       # SGI C++
+       archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+       # Archives containing C++ object files must be created using
+       # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test "$with_gnu_ld" = no; then
+           archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+         else
+           archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+         fi
+       fi
+       link_all_deplibs_CXX=yes
+       ;;
+    esac
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+       archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir'
+       export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+       ;;
+      icpc)
+       # Intel C++
+       with_gnu_ld=yes
+       archive_cmds_need_lc_CXX=no
+       archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+       whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+       ;;
+      cxx)
+       # Compaq C++
+       archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+       runpath_var=LD_RUN_PATH
+       hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      hardcode_libdir_flag_spec_CXX='-R$libdir'
+      hardcode_direct_CXX=yes
+      hardcode_shlibpath_var_CXX=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+
+       ;;
+      RCC)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      cxx)
+       allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+         archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+         hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+         hardcode_libdir_separator_CXX=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         ld_shlibs_CXX=no
+       fi
+       ;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Archives containing C++ object files must be created using
+       # the KAI C++ compiler.
+       old_archive_cmds_CXX='$CC -o $oldlib $oldobjs'
+       ;;
+      RCC)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      cxx)
+       allow_undefined_flag_CXX=' -expect_unresolved \*'
+       archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+       archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+         echo "-hidden">> $lib.exp~
+         $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~
+         $rm $lib.exp'
+
+       hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+        archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+         hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+         hardcode_libdir_separator_CXX=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         ld_shlibs_CXX=no
+       fi
+       ;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  sco*)
+    archive_cmds_need_lc_CXX=no
+    case $cc_basename in
+      CC)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC)
+       # Sun C++ 4.x
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      lcc)
+       # Lucid
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC)
+       # Sun C++ 4.2, 5.x and Centerline C++
+       no_undefined_flag_CXX=' -zdefs'
+       archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+       archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+       hardcode_libdir_flag_spec_CXX='-R$libdir'
+       hardcode_shlibpath_var_CXX=no
+       case $host_os in
+         solaris2.0-5 | solaris2.0-5.*) ;;
+         *)
+           # The C++ compiler is used as linker so we must use $wl
+           # flag to pass the commands to the underlying system
+           # linker.
+           # Supported since Solaris 2.6 (maybe 2.5.1?)
+           whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+           ;;
+       esac
+       link_all_deplibs_CXX=yes
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       # Archives containing C++ object files must be created using
+       # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+       ;;
+      gcx)
+       # Green Hills C++ Compiler
+       archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+       # The C++ compiler must be used to create the archive.
+       old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+       ;;
+      *)
+       # GNU C++ compiler with Solaris linker
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+         if $CC --version | grep -v '^2\.7' > /dev/null; then
+           archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         else
+           # g++ 2.7 appears to require `-G' NOT `-shared' on this
+           # platform.
+           archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         fi
+
+         hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+       fi
+       ;;
+    esac
+    ;;
+  sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
+    archive_cmds_need_lc_CXX=no
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC)
+       # NonStop-UX NCC 3.20
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+esac
+echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+GCC_CXX="$GXX"
+LD_CXX="$LD"
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+
+cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+
+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
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+         || test $p = "-R"; then
+        prev=$p
+        continue
+       else
+        prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        case $p in
+        -L* | -R*)
+          # Internal compiler library paths should come after those
+          # provided the user.  The postdeps already come after the
+          # user supplied libs so there is no need to process them.
+          if test -z "$compiler_lib_search_path_CXX"; then
+            compiler_lib_search_path_CXX="${prev}${p}"
+          else
+            compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+          fi
+          ;;
+        # The "-l" case would never come before the object being
+        # linked, so don't bother handling this case.
+        esac
+       else
+        if test -z "$postdeps_CXX"; then
+          postdeps_CXX="${prev}${p}"
+        else
+          postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+        fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+        pre_test_object_deps_done=yes
+        continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        if test -z "$predep_objects_CXX"; then
+          predep_objects_CXX="$p"
+        else
+          predep_objects_CXX="$predep_objects_CXX $p"
+        fi
+       else
+        if test -z "$postdep_objects_CXX"; then
+          postdep_objects_CXX="$p"
+        else
+          postdep_objects_CXX="$postdep_objects_CXX $p"
+        fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$rm -f confest.$objext
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+
+lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       ;;
+      *)
+       lt_prog_compiler_pic_CXX='-fPIC'
+       ;;
+      esac
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+       # All AIX code is PIC.
+       if test "$host_cpu" = ia64; then
+         # AIX 5 now supports IA64 processor
+         lt_prog_compiler_static_CXX='-Bstatic'
+       else
+         lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+       fi
+       ;;
+      chorus*)
+       case $cc_basename in
+       cxch68)
+         # Green Hills C++ Compiler
+         # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+         ;;
+       esac
+       ;;
+      dgux*)
+       case $cc_basename in
+         ec++)
+           lt_prog_compiler_pic_CXX='-KPIC'
+           ;;
+         ghcx)
+           # Green Hills C++ Compiler
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      freebsd* | kfreebsd*-gnu)
+       # FreeBSD uses GNU C++
+       ;;
+      hpux9* | hpux10* | hpux11*)
+       case $cc_basename in
+         CC)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+           if test "$host_cpu" != ia64; then
+             lt_prog_compiler_pic_CXX='+Z'
+           fi
+           ;;
+         aCC)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+           case "$host_cpu" in
+           hppa*64*|ia64*)
+             # +Z the default
+             ;;
+           *)
+             lt_prog_compiler_pic_CXX='+Z'
+             ;;
+           esac
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      irix5* | irix6* | nonstopux*)
+       case $cc_basename in
+         CC)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX='-non_shared'
+           # CC pic flag -KPIC is the default.
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      linux*)
+       case $cc_basename in
+         KCC)
+           # KAI C++ Compiler
+           lt_prog_compiler_wl_CXX='--backend -Wl,'
+           lt_prog_compiler_pic_CXX='-fPIC'
+           ;;
+         icpc)
+           # Intel C++
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-static'
+           ;;
+         cxx)
+           # Compaq C++
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           lt_prog_compiler_pic_CXX=
+           lt_prog_compiler_static_CXX='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      lynxos*)
+       ;;
+      m88k*)
+       ;;
+      mvs*)
+       case $cc_basename in
+         cxx)
+           lt_prog_compiler_pic_CXX='-W c,exportall'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      netbsd*)
+       ;;
+      osf3* | osf4* | osf5*)
+       case $cc_basename in
+         KCC)
+           lt_prog_compiler_wl_CXX='--backend -Wl,'
+           ;;
+         RCC)
+           # Rational C++ 2.4.1
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         cxx)
+           # Digital/Compaq C++
+           lt_prog_compiler_wl_CXX='-Wl,'
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           lt_prog_compiler_pic_CXX=
+           lt_prog_compiler_static_CXX='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      psos*)
+       ;;
+      sco*)
+       case $cc_basename in
+         CC)
+           lt_prog_compiler_pic_CXX='-fPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      solaris*)
+       case $cc_basename in
+         CC)
+           # Sun C++ 4.2, 5.x and Centerline C++
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           lt_prog_compiler_wl_CXX='-Qoption ld '
+           ;;
+         gcx)
+           # Green Hills C++ Compiler
+           lt_prog_compiler_pic_CXX='-PIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sunos4*)
+       case $cc_basename in
+         CC)
+           # Sun C++ 4.x
+           lt_prog_compiler_pic_CXX='-pic'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           ;;
+         lcc)
+           # Lucid
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      tandem*)
+       case $cc_basename in
+         NCC)
+           # NonStop-UX NCC 3.20
+           lt_prog_compiler_pic_CXX='-KPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      unixware*)
+       ;;
+      vxworks*)
+       ;;
+      *)
+       lt_prog_compiler_can_build_shared_CXX=no
+       ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_CXX=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:17536: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:17540: \$? = $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
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6
+
+if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:17596: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:17600: \$? = $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
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+
+echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_CXX
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+        allow_undefined_flag_CXX=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc_CXX=no
+        else
+         archive_cmds_need_lc_CXX=yes
+        fi
+        allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" || \
+   test -n "$runpath_var CXX" || \
+   test "X$hardcode_automatic_CXX"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
+echo "${ECHO_T}$hardcode_action_CXX" >&6
+
+if test "$hardcode_action_CXX" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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_cxx_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
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+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 shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); 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 shl_load
+
+/* 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 shl_load ();
+/* 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_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  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_cxx_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
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  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_cxx_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
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+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_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+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 dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); 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 dlopen
+
+/* 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 dlopen ();
+/* 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_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  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_cxx_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
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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_cxx_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
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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_cxx_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
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+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_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  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_cxx_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
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+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_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 18957 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 19055 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_CXX \
+    CC_CXX \
+    LD_CXX \
+    lt_prog_compiler_wl_CXX \
+    lt_prog_compiler_pic_CXX \
+    lt_prog_compiler_static_CXX \
+    lt_prog_compiler_no_builtin_flag_CXX \
+    export_dynamic_flag_spec_CXX \
+    thread_safe_flag_spec_CXX \
+    whole_archive_flag_spec_CXX \
+    enable_shared_with_static_runtimes_CXX \
+    old_archive_cmds_CXX \
+    old_archive_from_new_cmds_CXX \
+    predep_objects_CXX \
+    postdep_objects_CXX \
+    predeps_CXX \
+    postdeps_CXX \
+    compiler_lib_search_path_CXX \
+    archive_cmds_CXX \
+    archive_expsym_cmds_CXX \
+    postinstall_cmds_CXX \
+    postuninstall_cmds_CXX \
+    old_archive_from_expsyms_cmds_CXX \
+    allow_undefined_flag_CXX \
+    no_undefined_flag_CXX \
+    export_symbols_cmds_CXX \
+    hardcode_libdir_flag_spec_CXX \
+    hardcode_libdir_flag_spec_ld_CXX \
+    hardcode_libdir_separator_CXX \
+    hardcode_automatic_CXX \
+    module_cmds_CXX \
+    module_expsym_cmds_CXX \
+    lt_cv_prog_compiler_c_o_CXX \
+    exclude_expsyms_CXX \
+    include_expsyms_CXX; do
+
+    case $var in
+    old_archive_cmds_CXX | \
+    old_archive_from_new_cmds_CXX | \
+    archive_cmds_CXX | \
+    archive_expsym_cmds_CXX | \
+    module_cmds_CXX | \
+    module_expsym_cmds_CXX | \
+    old_archive_from_expsyms_cmds_CXX | \
+    export_symbols_cmds_CXX | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_CXX
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_CXX
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_CXX
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_CXX"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+
+       else
+         tagname=""
+       fi
+       ;;
+
+      F77)
+       if test -n "$F77" && test "X$F77" != "Xno"; then
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+
+archive_cmds_need_lc_F77=no
+allow_undefined_flag_F77=
+always_export_symbols_F77=no
+archive_expsym_cmds_F77=
+export_dynamic_flag_spec_F77=
+hardcode_direct_F77=no
+hardcode_libdir_flag_spec_F77=
+hardcode_libdir_flag_spec_ld_F77=
+hardcode_libdir_separator_F77=
+hardcode_minus_L_F77=no
+hardcode_automatic_F77=no
+module_cmds_F77=
+module_expsym_cmds_F77=
+link_all_deplibs_F77=unknown
+old_archive_cmds_F77=$old_archive_cmds
+no_undefined_flag_F77=
+whole_archive_flag_spec_F77=
+enable_shared_with_static_runtimes_F77=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+objext_F77=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+compiler_F77=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+GCC_F77="$G77"
+LD_F77="$LD"
+
+lt_prog_compiler_wl_F77=
+lt_prog_compiler_pic_F77=
+lt_prog_compiler_static_F77=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_F77='-Wl,'
+    lt_prog_compiler_static_F77='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_F77='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_F77=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic_F77=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_F77='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_F77='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_F77='-Bstatic'
+      else
+       lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_F77='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+       lt_prog_compiler_wl_F77='-Wl,'
+       lt_prog_compiler_pic_F77='-KPIC'
+       lt_prog_compiler_static_F77='-static'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_F77='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_F77='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_prog_compiler_pic_F77='-Kpic'
+      lt_prog_compiler_static_F77='-dn'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_F77='-Qoption ld '
+      lt_prog_compiler_pic_F77='-PIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_prog_compiler_pic_F77='-Kconform_pic'
+       lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_F77='-pic'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_F77"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_F77=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_F77"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:19882: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:19886: \$? = $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
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works_F77=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6
+
+if test x"$lt_prog_compiler_pic_works_F77" = xyes; then
+    case $lt_prog_compiler_pic_F77 in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
+     esac
+else
+    lt_prog_compiler_pic_F77=
+     lt_prog_compiler_can_build_shared_F77=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_F77=
+    ;;
+  *)
+    lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_F77=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:19942: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:19946: \$? = $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
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o_F77=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag_F77=
+  enable_shared_with_static_runtimes_F77=no
+  archive_cmds_F77=
+  archive_expsym_cmds_F77=
+  old_archive_From_new_cmds_F77=
+  old_archive_from_expsyms_cmds_F77=
+  export_dynamic_flag_spec_F77=
+  whole_archive_flag_spec_F77=
+  thread_safe_flag_spec_F77=
+  hardcode_libdir_flag_spec_F77=
+  hardcode_libdir_flag_spec_ld_F77=
+  hardcode_libdir_separator_F77=
+  hardcode_direct_F77=no
+  hardcode_minus_L_F77=no
+  hardcode_shlibpath_var_F77=unsupported
+  link_all_deplibs_F77=unknown
+  hardcode_automatic_F77=no
+  module_cmds_F77=
+  module_expsym_cmds_F77=
+  always_export_symbols_F77=no
+  export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_F77=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_F77=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       ld_shlibs_F77=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_F77=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       allow_undefined_flag_F77=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=no
+      enable_shared_with_static_runtimes_F77=yes
+      export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       ld_shlibs_F77=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+
+    sunos4*)
+      archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_cmds_F77="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        archive_expsym_cmds_F77="$tmp_archive_cmds"
+      fi
+    else
+      ld_shlibs_F77=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_F77" = yes; then
+      runpath_var=LD_RUN_PATH
+      hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
+      export_dynamic_flag_spec_F77='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       whole_archive_flag_spec_F77=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=yes
+      archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_F77=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       hardcode_direct_F77=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       else
+         export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_F77=''
+      hardcode_direct_F77=yes
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.012|aix4.012.*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         hardcode_direct_F77=yes
+         else
+         # We have old collect2
+         hardcode_direct_F77=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L_F77=yes
+         hardcode_libdir_flag_spec_F77='-L$libdir'
+         hardcode_libdir_separator_F77=
+         fi
+       esac
+       shared_flag='-shared'
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+       if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+       fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_F77=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag_F77='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_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_f77_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+       archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
+         allow_undefined_flag_F77="-z nodefs"
+         archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_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_f77_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         no_undefined_flag_F77=' ${wl}-bernotok'
+         allow_undefined_flag_F77=' ${wl}-berok'
+         # -bexpall does not export symbols beginning with underscore (_)
+         always_export_symbols_F77=yes
+         # Exported symbols can be pulled into shared objects from archives
+         whole_archive_flag_spec_F77=' '
+         archive_cmds_need_lc_F77=yes
+         # This is similar to how AIX traditionally builds it's shared libraries.
+         archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_F77=no
+      ;;
+
+    bsdi4*)
+      export_dynamic_flag_spec_F77=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_F77=' '
+      allow_undefined_flag_F77=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_F77='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_F77=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      archive_cmds_need_lc_F77=no
+      case "$host_os" in
+      rhapsody* | darwin1.[012])
+       allow_undefined_flag_F77='-undefined suppress'
+       ;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       allow_undefined_flag_F77='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag_F77='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag_F77='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+       ;;
+      esac
+       lt_int_apple_cc_single_mod=no
+       output_verbose_link_cmd='echo'
+       if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+         lt_int_apple_cc_single_mod=yes
+       fi
+       if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+         archive_cmds_F77='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+       else
+        archive_cmds_F77='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      module_cmds_F77='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      hardcode_direct_F77=no
+      hardcode_automatic_F77=yes
+      hardcode_shlibpath_var_F77=unsupported
+      whole_archive_flag_spec_F77='-all_load $convenience'
+      link_all_deplibs_F77=yes
+    else
+      ld_shlibs_F77=no
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_F77=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_direct_F77=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       *)
+         archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*)
+         hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+         hardcode_libdir_flag_spec_ld_F77='+b $libdir'
+         hardcode_libdir_separator_F77=:
+         hardcode_direct_F77=no
+         hardcode_shlibpath_var_F77=no
+         ;;
+       ia64*)
+         hardcode_libdir_flag_spec_F77='-L$libdir'
+         hardcode_direct_F77=no
+         hardcode_shlibpath_var_F77=no
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L_F77=yes
+         ;;
+       *)
+         hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+         hardcode_libdir_separator_F77=:
+         hardcode_direct_F77=yes
+         export_dynamic_flag_spec_F77='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L_F77=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_ld_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      link_all_deplibs_F77=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    newsos6)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec_F77='${wl}-E'
+      else
+       case $host_os in
+        openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+          archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          hardcode_libdir_flag_spec_F77='-R$libdir'
+          ;;
+        *)
+          archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      allow_undefined_flag_F77=unsupported
+      archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       allow_undefined_flag_F77=' -expect_unresolved \*'
+       archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      else
+       allow_undefined_flag_F77=' -expect_unresolved \*'
+       archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       hardcode_libdir_flag_spec_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    sco3.2v5*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_F77=no
+      export_dynamic_flag_spec_F77='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      no_undefined_flag_F77=' -z text'
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_shlibpath_var_F77=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+       whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
+      esac
+      link_all_deplibs_F77=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_F77=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         reload_cmds_F77='$CC -r -o $output$reload_objs'
+         hardcode_direct_F77=no
+        ;;
+       motorola)
+         archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_F77=no
+      export_dynamic_flag_spec_F77='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_shlibpath_var_F77=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       ld_shlibs_F77=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
+      no_undefined_flag_F77='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv5*)
+      no_undefined_flag_F77=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      hardcode_libdir_flag_spec_F77=
+      hardcode_shlibpath_var_F77=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      ld_shlibs_F77=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
+echo "${ECHO_T}$ld_shlibs_F77" >&6
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_F77" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_F77=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_F77 in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_F77
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_F77
+        allow_undefined_flag_F77=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc_F77=no
+        else
+         archive_cmds_need_lc_F77=yes
+        fi
+        allow_undefined_flag_F77=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_F77=
+if test -n "$hardcode_libdir_flag_spec_F77" || \
+   test -n "$runpath_var F77" || \
+   test "X$hardcode_automatic_F77"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_F77" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
+     test "$hardcode_minus_L_F77" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_F77=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_F77=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_F77=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
+echo "${ECHO_T}$hardcode_action_F77" >&6
+
+if test "$hardcode_action_F77" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_F77 \
+    CC_F77 \
+    LD_F77 \
+    lt_prog_compiler_wl_F77 \
+    lt_prog_compiler_pic_F77 \
+    lt_prog_compiler_static_F77 \
+    lt_prog_compiler_no_builtin_flag_F77 \
+    export_dynamic_flag_spec_F77 \
+    thread_safe_flag_spec_F77 \
+    whole_archive_flag_spec_F77 \
+    enable_shared_with_static_runtimes_F77 \
+    old_archive_cmds_F77 \
+    old_archive_from_new_cmds_F77 \
+    predep_objects_F77 \
+    postdep_objects_F77 \
+    predeps_F77 \
+    postdeps_F77 \
+    compiler_lib_search_path_F77 \
+    archive_cmds_F77 \
+    archive_expsym_cmds_F77 \
+    postinstall_cmds_F77 \
+    postuninstall_cmds_F77 \
+    old_archive_from_expsyms_cmds_F77 \
+    allow_undefined_flag_F77 \
+    no_undefined_flag_F77 \
+    export_symbols_cmds_F77 \
+    hardcode_libdir_flag_spec_F77 \
+    hardcode_libdir_flag_spec_ld_F77 \
+    hardcode_libdir_separator_F77 \
+    hardcode_automatic_F77 \
+    module_cmds_F77 \
+    module_expsym_cmds_F77 \
+    lt_cv_prog_compiler_c_o_F77 \
+    exclude_expsyms_F77 \
+    include_expsyms_F77; do
+
+    case $var in
+    old_archive_cmds_F77 | \
+    old_archive_from_new_cmds_F77 | \
+    archive_cmds_F77 | \
+    archive_expsym_cmds_F77 | \
+    module_cmds_F77 | \
+    module_expsym_cmds_F77 | \
+    old_archive_from_expsyms_cmds_F77 | \
+    export_symbols_cmds_F77 | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_F77
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_F77
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_F77
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_F77
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_F77
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_F77
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_F77
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_F77
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_F77
+archive_expsym_cmds=$lt_archive_expsym_cmds_F77
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_F77
+module_expsym_cmds=$lt_module_expsym_cmds_F77
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_F77
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_F77
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_F77
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_F77
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_F77
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_F77
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_F77
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_F77
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_F77
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_F77
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_F77"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_F77
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_F77
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_F77
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_F77
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+       else
+         tagname=""
+       fi
+       ;;
+
+      GCJ)
+       if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+
+
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+objext_GCJ=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+compiler_GCJ=$CC
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+archive_cmds_need_lc_GCJ=no
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+
+lt_prog_compiler_no_builtin_flag_GCJ=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:21980: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:21984: \$? = $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
+     if test ! -s conftest.err; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl_GCJ=
+lt_prog_compiler_pic_GCJ=
+lt_prog_compiler_static_GCJ=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_GCJ='-Wl,'
+    lt_prog_compiler_static_GCJ='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_GCJ='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_GCJ=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic_GCJ=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_GCJ='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_GCJ='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_GCJ='-Bstatic'
+      else
+       lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_GCJ='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+       lt_prog_compiler_wl_GCJ='-Wl,'
+       lt_prog_compiler_pic_GCJ='-KPIC'
+       lt_prog_compiler_static_GCJ='-static'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_GCJ='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_GCJ='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_prog_compiler_pic_GCJ='-Kpic'
+      lt_prog_compiler_static_GCJ='-dn'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_GCJ='-Qoption ld '
+      lt_prog_compiler_pic_GCJ='-PIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_prog_compiler_pic_GCJ='-Kconform_pic'
+       lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_GCJ='-pic'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_GCJ=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_GCJ"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_GCJ=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_GCJ"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:22213: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:22217: \$? = $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
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works_GCJ=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6
+
+if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then
+    case $lt_prog_compiler_pic_GCJ in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;;
+     esac
+else
+    lt_prog_compiler_pic_GCJ=
+     lt_prog_compiler_can_build_shared_GCJ=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_GCJ=
+    ;;
+  *)
+    lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_GCJ=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:22273: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:22277: \$? = $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
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o_GCJ=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag_GCJ=
+  enable_shared_with_static_runtimes_GCJ=no
+  archive_cmds_GCJ=
+  archive_expsym_cmds_GCJ=
+  old_archive_From_new_cmds_GCJ=
+  old_archive_from_expsyms_cmds_GCJ=
+  export_dynamic_flag_spec_GCJ=
+  whole_archive_flag_spec_GCJ=
+  thread_safe_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_ld_GCJ=
+  hardcode_libdir_separator_GCJ=
+  hardcode_direct_GCJ=no
+  hardcode_minus_L_GCJ=no
+  hardcode_shlibpath_var_GCJ=unsupported
+  link_all_deplibs_GCJ=unknown
+  hardcode_automatic_GCJ=no
+  module_cmds_GCJ=
+  module_expsym_cmds_GCJ=
+  always_export_symbols_GCJ=no
+  export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_GCJ=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_GCJ=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       ld_shlibs_GCJ=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_GCJ=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       allow_undefined_flag_GCJ=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=no
+      enable_shared_with_static_runtimes_GCJ=yes
+      export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       ld_shlibs_GCJ=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    sunos4*)
+      archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_cmds_GCJ="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        archive_expsym_cmds_GCJ="$tmp_archive_cmds"
+      fi
+    else
+      ld_shlibs_GCJ=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_GCJ" = yes; then
+      runpath_var=LD_RUN_PATH
+      hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
+      export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       whole_archive_flag_spec_GCJ=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=yes
+      archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_GCJ=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       hardcode_direct_GCJ=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       else
+         export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_GCJ=''
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_separator_GCJ=':'
+      link_all_deplibs_GCJ=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.012|aix4.012.*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         hardcode_direct_GCJ=yes
+         else
+         # We have old collect2
+         hardcode_direct_GCJ=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L_GCJ=yes
+         hardcode_libdir_flag_spec_GCJ='-L$libdir'
+         hardcode_libdir_separator_GCJ=
+         fi
+       esac
+       shared_flag='-shared'
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+       if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+       fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_GCJ=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag_GCJ='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       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
+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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+       archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
+         allow_undefined_flag_GCJ="-z nodefs"
+         archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        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
+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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         no_undefined_flag_GCJ=' ${wl}-bernotok'
+         allow_undefined_flag_GCJ=' ${wl}-berok'
+         # -bexpall does not export symbols beginning with underscore (_)
+         always_export_symbols_GCJ=yes
+         # Exported symbols can be pulled into shared objects from archives
+         whole_archive_flag_spec_GCJ=' '
+         archive_cmds_need_lc_GCJ=yes
+         # This is similar to how AIX traditionally builds it's shared libraries.
+         archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_GCJ=no
+      ;;
+
+    bsdi4*)
+      export_dynamic_flag_spec_GCJ=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ=' '
+      allow_undefined_flag_GCJ=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_GCJ='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_GCJ=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      archive_cmds_need_lc_GCJ=no
+      case "$host_os" in
+      rhapsody* | darwin1.[012])
+       allow_undefined_flag_GCJ='-undefined suppress'
+       ;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+       allow_undefined_flag_GCJ='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag_GCJ='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag_GCJ='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+       ;;
+      esac
+       lt_int_apple_cc_single_mod=no
+       output_verbose_link_cmd='echo'
+       if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+         lt_int_apple_cc_single_mod=yes
+       fi
+       if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+         archive_cmds_GCJ='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+       else
+        archive_cmds_GCJ='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      module_cmds_GCJ='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      hardcode_direct_GCJ=no
+      hardcode_automatic_GCJ=yes
+      hardcode_shlibpath_var_GCJ=unsupported
+      whole_archive_flag_spec_GCJ='-all_load $convenience'
+      link_all_deplibs_GCJ=yes
+    else
+      ld_shlibs_GCJ=no
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_GCJ=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_direct_GCJ=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_GCJ=yes
+      export_dynamic_flag_spec_GCJ='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case "$host_cpu" in
+       hppa*64*|ia64*)
+         archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       *)
+         archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       case "$host_cpu" in
+       hppa*64*)
+         hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+         hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
+         hardcode_libdir_separator_GCJ=:
+         hardcode_direct_GCJ=no
+         hardcode_shlibpath_var_GCJ=no
+         ;;
+       ia64*)
+         hardcode_libdir_flag_spec_GCJ='-L$libdir'
+         hardcode_direct_GCJ=no
+         hardcode_shlibpath_var_GCJ=no
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L_GCJ=yes
+         ;;
+       *)
+         hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+         hardcode_libdir_separator_GCJ=:
+         hardcode_direct_GCJ=yes
+         export_dynamic_flag_spec_GCJ='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L_GCJ=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    newsos6)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec_GCJ='${wl}-E'
+      else
+       case $host_os in
+        openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+          archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          hardcode_libdir_flag_spec_GCJ='-R$libdir'
+          ;;
+        *)
+          archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      allow_undefined_flag_GCJ=unsupported
+      archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       allow_undefined_flag_GCJ=' -expect_unresolved \*'
+       archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      else
+       allow_undefined_flag_GCJ=' -expect_unresolved \*'
+       archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       hardcode_libdir_flag_spec_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    sco3.2v5*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_GCJ=no
+      export_dynamic_flag_spec_GCJ='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      no_undefined_flag_GCJ=' -z text'
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+       whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
+      esac
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_GCJ=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         reload_cmds_GCJ='$CC -r -o $output$reload_objs'
+         hardcode_direct_GCJ=no
+        ;;
+       motorola)
+         archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_GCJ=no
+      export_dynamic_flag_spec_GCJ='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_shlibpath_var_GCJ=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       ld_shlibs_GCJ=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
+      no_undefined_flag_GCJ='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv5*)
+      no_undefined_flag_GCJ=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      hardcode_libdir_flag_spec_GCJ=
+      hardcode_shlibpath_var_GCJ=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    *)
+      ld_shlibs_GCJ=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
+echo "${ECHO_T}$ld_shlibs_GCJ" >&6
+test "$ld_shlibs_GCJ" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_GCJ" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_GCJ=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_GCJ in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_GCJ
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ
+        allow_undefined_flag_GCJ=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc_GCJ=no
+        else
+         archive_cmds_need_lc_GCJ=yes
+        fi
+        allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_GCJ=
+if test -n "$hardcode_libdir_flag_spec_GCJ" || \
+   test -n "$runpath_var GCJ" || \
+   test "X$hardcode_automatic_GCJ"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_GCJ" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
+     test "$hardcode_minus_L_GCJ" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_GCJ=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_GCJ=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_GCJ=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
+echo "${ECHO_T}$hardcode_action_GCJ" >&6
+
+if test "$hardcode_action_GCJ" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+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 shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); 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 shl_load
+
+/* 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 shl_load ();
+/* 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_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  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
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  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
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+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_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+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 dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); 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 dlopen
+
+/* 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 dlopen ();
+/* 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_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  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
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+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_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  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
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+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_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 24457 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 24555 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_GCJ \
+    CC_GCJ \
+    LD_GCJ \
+    lt_prog_compiler_wl_GCJ \
+    lt_prog_compiler_pic_GCJ \
+    lt_prog_compiler_static_GCJ \
+    lt_prog_compiler_no_builtin_flag_GCJ \
+    export_dynamic_flag_spec_GCJ \
+    thread_safe_flag_spec_GCJ \
+    whole_archive_flag_spec_GCJ \
+    enable_shared_with_static_runtimes_GCJ \
+    old_archive_cmds_GCJ \
+    old_archive_from_new_cmds_GCJ \
+    predep_objects_GCJ \
+    postdep_objects_GCJ \
+    predeps_GCJ \
+    postdeps_GCJ \
+    compiler_lib_search_path_GCJ \
+    archive_cmds_GCJ \
+    archive_expsym_cmds_GCJ \
+    postinstall_cmds_GCJ \
+    postuninstall_cmds_GCJ \
+    old_archive_from_expsyms_cmds_GCJ \
+    allow_undefined_flag_GCJ \
+    no_undefined_flag_GCJ \
+    export_symbols_cmds_GCJ \
+    hardcode_libdir_flag_spec_GCJ \
+    hardcode_libdir_flag_spec_ld_GCJ \
+    hardcode_libdir_separator_GCJ \
+    hardcode_automatic_GCJ \
+    module_cmds_GCJ \
+    module_expsym_cmds_GCJ \
+    lt_cv_prog_compiler_c_o_GCJ \
+    exclude_expsyms_GCJ \
+    include_expsyms_GCJ; do
+
+    case $var in
+    old_archive_cmds_GCJ | \
+    old_archive_from_new_cmds_GCJ | \
+    archive_cmds_GCJ | \
+    archive_expsym_cmds_GCJ | \
+    module_cmds_GCJ | \
+    module_expsym_cmds_GCJ | \
+    old_archive_from_expsyms_cmds_GCJ | \
+    export_symbols_cmds_GCJ | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_GCJ
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_GCJ
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_GCJ
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_GCJ
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_GCJ
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_GCJ
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_GCJ
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_GCJ
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_GCJ
+archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_GCJ
+module_expsym_cmds=$lt_module_expsym_cmds_GCJ
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_GCJ
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_GCJ
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_GCJ
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_GCJ
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_GCJ
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_GCJ
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_GCJ
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_GCJ
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_GCJ
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_GCJ"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_GCJ
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_GCJ
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_GCJ
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_GCJ
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+       else
+         tagname=""
+       fi
+       ;;
+
+      RC)
+
+
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+objext_RC=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+compiler_RC=$CC
+lt_cv_prog_compiler_c_o_RC=yes
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_RC \
+    CC_RC \
+    LD_RC \
+    lt_prog_compiler_wl_RC \
+    lt_prog_compiler_pic_RC \
+    lt_prog_compiler_static_RC \
+    lt_prog_compiler_no_builtin_flag_RC \
+    export_dynamic_flag_spec_RC \
+    thread_safe_flag_spec_RC \
+    whole_archive_flag_spec_RC \
+    enable_shared_with_static_runtimes_RC \
+    old_archive_cmds_RC \
+    old_archive_from_new_cmds_RC \
+    predep_objects_RC \
+    postdep_objects_RC \
+    predeps_RC \
+    postdeps_RC \
+    compiler_lib_search_path_RC \
+    archive_cmds_RC \
+    archive_expsym_cmds_RC \
+    postinstall_cmds_RC \
+    postuninstall_cmds_RC \
+    old_archive_from_expsyms_cmds_RC \
+    allow_undefined_flag_RC \
+    no_undefined_flag_RC \
+    export_symbols_cmds_RC \
+    hardcode_libdir_flag_spec_RC \
+    hardcode_libdir_flag_spec_ld_RC \
+    hardcode_libdir_separator_RC \
+    hardcode_automatic_RC \
+    module_cmds_RC \
+    module_expsym_cmds_RC \
+    lt_cv_prog_compiler_c_o_RC \
+    exclude_expsyms_RC \
+    include_expsyms_RC; do
+
+    case $var in
+    old_archive_cmds_RC | \
+    old_archive_from_new_cmds_RC | \
+    archive_cmds_RC | \
+    archive_expsym_cmds_RC | \
+    module_cmds_RC | \
+    module_expsym_cmds_RC | \
+    old_archive_from_expsyms_cmds_RC | \
+    export_symbols_cmds_RC | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_RC
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_RC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_RC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_RC
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_RC
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_RC
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_RC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_RC
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_RC
+archive_expsym_cmds=$lt_archive_expsym_cmds_RC
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_RC
+module_expsym_cmds=$lt_module_expsym_cmds_RC
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_RC
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_RC
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_RC
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_RC
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_RC
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_RC
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_RC
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_RC
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_RC
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_RC
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_RC"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_RC
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_RC
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_RC
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_RC
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+       ;;
+
+      *)
+       { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5
+echo "$as_me: error: Unsupported tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+       ;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5
+echo "$as_me: error: unable to update list of available tagged configurations." >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+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 ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  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_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+
+       echo "$as_me:$LINENO: checking for working volatile" >&5
+echo $ECHO_N "checking for working volatile... $ECHO_C" >&6
+if test "${amanda_cv_c_volatile+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 ()
+{
+
+                       volatile int aaa = 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
+  amanda_cv_c_volatile=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_c_volatile=no
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_c_volatile" >&5
+echo "${ECHO_T}$amanda_cv_c_volatile" >&6
+       if test $amanda_cv_c_volatile = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define volatile
+_ACEOF
+
+       fi
+
+
+
+       echo "$as_me:$LINENO: checking for working unsigned long constants" >&5
+echo $ECHO_N "checking for working unsigned long constants... $ECHO_C" >&6
+if test "${amanda_cv_c_unsigned_long_constants+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 ()
+{
+
+                       long l = 1ul;
+
+  ;
+  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_c_unsigned_long_constants=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_c_unsigned_long_constants=no
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_c_unsigned_long_constants" >&5
+echo "${ECHO_T}$amanda_cv_c_unsigned_long_constants" >&6
+       if test "$amanda_cv_c_unsigned_long_constants" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_UNSIGNED_LONG_CONSTANTS 1
+_ACEOF
+
+       fi
+
+
+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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((off_t *) 0)
+  return 0;
+if (sizeof (off_t))
+  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_off_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+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_off_t" >&5
+echo "${ECHO_T}$ac_cv_type_off_t" >&6
+if test $ac_cv_type_off_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+if test "${ac_cv_type_pid_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
+int
+main ()
+{
+if ((pid_t *) 0)
+  return 0;
+if (sizeof (pid_t))
+  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_pid_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_pid_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+if test $ac_cv_type_pid_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((size_t *) 0)
+  return 0;
+if (sizeof (size_t))
+  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_size_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+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_size_t" >&5
+echo "${ECHO_T}$ac_cv_type_size_t" >&6
+if test $ac_cv_type_size_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned
+_ACEOF
+
+fi
+
+
+
+
+
+
+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
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((ssize_t *) 0)
+  return 0;
+if (sizeof (ssize_t))
+  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_ssize_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+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_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
+if test $ac_cv_type_ssize_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define ssize_t int
+_ACEOF
+
+fi
+
+
+echo "$as_me:$LINENO: checking for unsigned long long" >&5
+echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6
+if test "${ac_cv_type_unsigned_long_long+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
+int
+main ()
+{
+if ((unsigned long long *) 0)
+  return 0;
+if (sizeof (unsigned 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); } &&
+        { 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_unsigned_long_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_unsigned_long_long=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5
+echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6
+if test $ac_cv_type_unsigned_long_long = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UNSIGNED_LONG_LONG 1
+_ACEOF
+
+
+fi
+
+
+
+
+
+
+echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
+echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6
+if test "${ac_cv_type_uid_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>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uid_t" >/dev/null 2>&1; then
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5
+echo "${ECHO_T}$ac_cv_type_uid_t" >&6
+if test $ac_cv_type_uid_t = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define uid_t int
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define gid_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+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>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  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_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
+echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
+if test "${ac_cv_struct_tm+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>
+#include <time.h>
+
+int
+main ()
+{
+struct tm *tp; tp->tm_sec;
+  ;
+  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_struct_tm=time.h
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5
+echo "${ECHO_T}$ac_cv_struct_tm" >&6
+if test $ac_cv_struct_tm = sys/time.h; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TM_IN_SYS_TIME 1
+_ACEOF
+
+fi
+
+for ac_prog in flex lex
+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_LEX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$LEX"; then
+  ac_cv_prog_LEX="$LEX" # 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_LEX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+  echo "$as_me:$LINENO: result: $LEX" >&5
+echo "${ECHO_T}$LEX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test -z "$LEXLIB"
+then
+  echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5
+echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6
+if test "${ac_cv_lib_fl_yywrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 yywrap ();
+int
+main ()
+{
+yywrap ();
+  ;
+  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
+  ac_cv_lib_fl_yywrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_fl_yywrap=no
+fi
+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_fl_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6
+if test $ac_cv_lib_fl_yywrap = yes; then
+  LEXLIB="-lfl"
+else
+  echo "$as_me:$LINENO: checking for yywrap in -ll" >&5
+echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6
+if test "${ac_cv_lib_l_yywrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ll  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 yywrap ();
+int
+main ()
+{
+yywrap ();
+  ;
+  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
+  ac_cv_lib_l_yywrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_l_yywrap=no
+fi
+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_l_yywrap" >&5
+echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6
+if test $ac_cv_lib_l_yywrap = yes; then
+  LEXLIB="-ll"
+fi
+
+fi
+
+fi
+
+if test "x$LEX" != "x:"; then
+  echo "$as_me:$LINENO: checking lex output file root" >&5
+echo $ECHO_N "checking lex output file root... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_root+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # The minimal lex program is just a single line: %%.  But some broken lexes
+# (Solaris, I think it was) want two %% lines, so accommodate them.
+cat >conftest.l <<_ACEOF
+%%
+%%
+_ACEOF
+{ (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5
+  (eval $LEX conftest.l) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+if test -f lex.yy.c; then
+  ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+  ac_cv_prog_lex_root=lexyy
+else
+  { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5
+echo "$as_me: error: cannot find output from $LEX; giving up" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_root" >&6
+rm -f conftest.l
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5
+echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6
+if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent. Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c
+ac_save_LIBS=$LIBS
+LIBS="$LIBS $LEXLIB"
+cat >conftest.$ac_ext <<_ACEOF
+`cat $LEX_OUTPUT_ROOT.c`
+_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
+  ac_cv_prog_lex_yytext_pointer=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+rm -f "${LEX_OUTPUT_ROOT}.c"
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5
+echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define YYTEXT_POINTER 1
+_ACEOF
+
+fi
+
+fi
+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 $ac_cv_type_socklen_t = no; 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 $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 <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+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_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (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
+  :
+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 )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+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>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+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
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  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
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in dir; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  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
+  ac_cv_search_opendir="-l$ac_lib"
+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_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+else
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  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
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in x; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  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
+  ac_cv_search_opendir="-l$ac_lib"
+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_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+fi
+
+
+
+
+
+for ac_header in sys/wait.h wait.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+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_header>
+_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_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+echo "$as_me:$LINENO: checking whether wait uses union wait" >&5
+echo $ECHO_N "checking whether wait uses union wait... $ECHO_C" >&6
+if test "${cf_cv_arg_union_wait+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 HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#else
+# if HAVE_WAIT_H
+#  include <wait.h>
+# endif
+#endif
+
+#ifdef __STDC__
+pid_t wait(union wait *);
+#endif
+
+int
+main ()
+{
+
+  union wait x; int i;
+  wait(&x); i = WIFEXITED(x)
+
+  ;
+  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
+  cf_cv_arg_union_wait=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cf_cv_arg_union_wait=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $cf_cv_arg_union_wait" >&5
+echo "${ECHO_T}$cf_cv_arg_union_wait" >&6
+if test $cf_cv_arg_union_wait = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WAIT_USES_UNION 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+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>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+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_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in \
+       arpa/inet.h \
+       camlib.h \
+       cam/cam.h \
+       cam/scsi/scsi_message.h \
+       chio.h \
+       db.h \
+       dbm.h \
+       fcntl.h \
+       fnmatch.h \
+       fstab.h \
+       grp.h \
+       history.h \
+       libc.h \
+       limits.h \
+       linux/zftape.h \
+       mntent.h \
+       mnttab.h \
+       ndbm.h \
+       netdb.h \
+       netinet/in_systm.h \
+       readline.h \
+       readline/history.h \
+       readline/readline.h \
+       scsi/sg.h \
+       scsi/scsi_ioctl.h \
+       stdlib.h \
+       string.h \
+       strings.h \
+       sys/chio.h \
+       sys/dsreq.h \
+       sys/fcntl.h \
+       sys/file.h \
+       sys/ioctl.h \
+       sys/ipc.h \
+       sys/mman.h \
+       sys/mntent.h \
+       sys/mtio.h \
+       sys/param.h \
+       sys/scarray.h \
+       sys/gscdds.h \
+       sys/scsiio.h \
+       sys/scsi.h \
+       sys/scsi/impl/uscsi.h \
+       sys/scsi/scsi/ioctl.h \
+       sys/select.h \
+       sys/shm.h \
+       sys/stat.h \
+       sys/statfs.h \
+       sys/statvfs.h \
+       sys/tape.h \
+       sys/time.h \
+       sys/types.h \
+       sys/vfs.h \
+       sys/vfstab.h \
+       syslog.h \
+       unistd.h \
+       vtblc.h \
+
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+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_header>
+_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_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in netinet/ip.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+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/socket.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#include <netinet/in.h>
+
+
+#include <$ac_header>
+_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
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in sys/mount.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+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 HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+
+#include <$ac_header>
+_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
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+NO_SCSI_CHANGER_MODE=true
+NO_CHIO_CHANGER_MODE=true
+
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+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>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  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
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+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>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  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_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  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
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+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
+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 ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_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_c_bigendian=no
+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 )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+
+if test x"$ac_cv_header_sys_scsi_h" = x"yes"; then
+    echo "$as_me:$LINENO: checking for HP/UX-like scsi changer support" >&5
+echo $ECHO_N "checking for HP/UX-like scsi changer support... $ECHO_C" >&6
+if test "${amanda_cv_hpux_scsi_chio+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/scsi.h>
+
+int
+main ()
+{
+
+       static struct element_addresses changer_info;
+       int i = SIOC_ELEMENT_ADDRESSES;
+       int j = SIOC_ELEMENT_STATUS;
+       int k = SIOC_MOVE_MEDIUM;
+
+  ;
+  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_hpux_scsi_chio=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_hpux_scsi_chio=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_hpux_scsi_chio" >&5
+echo "${ECHO_T}$amanda_cv_hpux_scsi_chio" >&6
+    if test x"$amanda_cv_hpux_scsi_chio" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HPUX_SCSI_CHIO 1
+_ACEOF
+
+       NO_SCSI_CHANGER_MODE=false
+    fi
+fi
+
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_scsi_scsi_ioctl_h" = x"yes"; then
+       echo "$as_me:$LINENO: checking for Linux like scsi support (ioctl)" >&5
+echo $ECHO_N "checking for Linux like scsi support (ioctl)... $ECHO_C" >&6
+if test "${amanda_cv_linux_scsi+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 <scsi/scsi_ioctl.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+       int device;
+       char *Command;
+       ioctl(device, SCSI_IOCTL_SEND_COMMAND, Command);
+
+  ;
+  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_linux_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_linux_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_linux_scsi" >&5
+echo "${ECHO_T}$amanda_cv_linux_scsi" >&6
+fi
+
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_scsi_sg_h" = x"yes"; then
+       echo "$as_me:$LINENO: checking for Linux like scsi support (sg)" >&5
+echo $ECHO_N "checking for Linux like scsi support (sg)... $ECHO_C" >&6
+if test "${amanda_cv_linux_sg_scsi+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 <scsi/sg.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+       int device;
+       struct sg_header *psg_header;
+       char *buffer;
+       write(device, buffer, 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
+  amanda_cv_linux_sg_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_linux_sg_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_linux_sg_scsi" >&5
+echo "${ECHO_T}$amanda_cv_linux_sg_scsi" >&6
+fi
+
+if test x"$amanda_cv_linux_scsi" = x"yes" ||
+ test x"$amanda_cv_linux_sg_scsi" = x"yes";then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LINUX_LIKE_SCSI 1
+_ACEOF
+
+       NO_SCSI_CHANGER_MODE=false
+fi
+
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scsi_h" = x"yes"; then
+       echo "$as_me:$LINENO: checking for HP-UX like scsi support" >&5
+echo $ECHO_N "checking for HP-UX like scsi support... $ECHO_C" >&6
+if test "${amanda_cv_hpux_scsi+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 <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/scsi.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+       int device;
+       char *Command;
+       ioctl(device, SIOC_IO, Command);
+
+  ;
+  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_hpux_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_hpux_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_hpux_scsi" >&5
+echo "${ECHO_T}$amanda_cv_hpux_scsi" >&6
+       if test x"$amanda_cv_hpux_scsi" = x"yes";then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HPUX_LIKE_SCSI 1
+_ACEOF
+
+               NO_SCSI_CHANGER_MODE=false
+               NO_CHIO_CHANGER_MODE=false
+       fi
+fi
+
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_dsreq_h" = x"yes"; then
+       echo "$as_me:$LINENO: checking for Irix like scsi support" >&5
+echo $ECHO_N "checking for Irix like scsi support... $ECHO_C" >&6
+if test "${amanda_cv_irix_scsi+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>
+#include <sys/dsreq.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+       int device=1;
+       char Command;
+       ioctl(device, DS_ENTER, &Command);
+
+  ;
+  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_irix_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_irix_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_irix_scsi" >&5
+echo "${ECHO_T}$amanda_cv_irix_scsi" >&6
+       if test x"$amanda_cv_irix_scsi" = x"yes";then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_IRIX_LIKE_SCSI 1
+_ACEOF
+
+               NO_SCSI_CHANGER_MODE=false
+       fi
+fi
+
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scsi_impl_uscsi_h" = x"yes"; then
+       echo "$as_me:$LINENO: checking for Solaris like scsi support" >&5
+echo $ECHO_N "checking for Solaris like scsi support... $ECHO_C" >&6
+if test "${amanda_cv_solaris_scsi+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>
+#include <sys/scsi/impl/uscsi.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+       int device;
+       char *Command;
+       ioctl(device, USCSICMD, Command);
+
+  ;
+  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_solaris_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_solaris_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_solaris_scsi" >&5
+echo "${ECHO_T}$amanda_cv_solaris_scsi" >&6
+       if test x"$amanda_cv_solaris_scsi" = x"yes";then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOLARIS_LIKE_SCSI 1
+_ACEOF
+
+               NO_SCSI_CHANGER_MODE=false
+       fi
+fi
+
+if test x"$ac_cv_header_sys_tape_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scarray_h" = x"yes" &&
+   test x"$ac_cv_header_sys_gscdds_h" = x"yes"; then
+       echo "$as_me:$LINENO: checking for AIX like scsi support" >&5
+echo $ECHO_N "checking for AIX like scsi support... $ECHO_C" >&6
+if test "${amanda_cv_aix_scsi+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>
+#include <sys/scarray.h>
+#include <sys/tape.h>
+
+int
+main ()
+{
+
+       int device;
+       char *Command;
+       ioctl(device, STIOCMD, Command);
+
+  ;
+  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_aix_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_aix_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_aix_scsi" >&5
+echo "${ECHO_T}$amanda_cv_aix_scsi" >&6
+       if test x"$amanda_cv_aix_scsi" = x"yes";then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AIX_LIKE_SCSI 1
+_ACEOF
+
+               NO_SCSI_CHANGER_MODE=false
+       fi
+fi
+if test x"$ac_cv_header_cam_cam_h" = x"yes";then
+       echo "$as_me:$LINENO: checking for CAM like scsi support" >&5
+echo $ECHO_N "checking for CAM like scsi support... $ECHO_C" >&6
+if test "${amanda_cv_cam_scsi+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 <stdio.h>
+# include <fcntl.h>
+# include <cam/cam.h>
+# include <cam/cam_ccb.h>
+# include <cam/scsi/scsi_message.h>
+# include <cam/scsi/scsi_pass.h>
+# include <camlib.h>
+
+int
+main ()
+{
+
+       struct cam_device *curdev;
+
+       curdev = cam_open_pass("", O_RDWR, NULL);
+
+  ;
+  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_cam_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_cam_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_cam_scsi" >&5
+echo "${ECHO_T}$amanda_cv_cam_scsi" >&6
+       if test x"$amanda_cv_cam_scsi" = x"yes";then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CAM_LIKE_SCSI 1
+_ACEOF
+
+               NO_SCSI_CHANGER_MODE=false
+
+echo "$as_me:$LINENO: checking for main in -lcam" >&5
+echo $ECHO_N "checking for main in -lcam... $ECHO_C" >&6
+if test "${ac_cv_lib_cam_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcam  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_cam_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_cam_main=no
+fi
+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_cam_main" >&5
+echo "${ECHO_T}$ac_cv_lib_cam_main" >&6
+if test $ac_cv_lib_cam_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCAM 1
+_ACEOF
+
+  LIBS="-lcam $LIBS"
+
+fi
+
+       fi
+fi
+
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scsiio_h" = x"yes"; then
+    echo "$as_me:$LINENO: checking for BSD like scsi support" >&5
+echo $ECHO_N "checking for BSD like scsi support... $ECHO_C" >&6
+if test "${amanda_cv_bsd_scsi+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>
+#include <sys/scsiio.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+    int device=1;
+    char Command;
+    ioctl(device, SCIOCCOMMAND, &Command);
+
+  ;
+  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_bsd_scsi=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_bsd_scsi=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_bsd_scsi" >&5
+echo "${ECHO_T}$amanda_cv_bsd_scsi" >&6
+    if test x"$amanda_cv_bsd_scsi" = x"yes";then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_BSD_LIKE_SCSI 1
+_ACEOF
+
+       NO_SCSI_CHANGER_MODE=false
+    fi
+fi
+
+if test x"$ac_cv_header_chio_h" = x"yes" ||
+   test x"$ac_cv_header_sys_chio_h" = x"yes"; then
+         if test x"$ac_cv_header_camlib_h" != x"yes"; then
+     if $NO_SCSI_CHANGER_MODE; then
+       NO_SCSI_CHANGER_MODE=false
+     else
+       NO_CHIO_CHANGER_MODE=false
+     fi
+   fi
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lcur_colr" >&5
+echo $ECHO_N "checking for main in -lcur_colr... $ECHO_C" >&6
+if test "${ac_cv_lib_cur_colr_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcur_colr  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_cur_colr_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_cur_colr_main=no
+fi
+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_cur_colr_main" >&5
+echo "${ECHO_T}$ac_cv_lib_cur_colr_main" >&6
+if test $ac_cv_lib_cur_colr_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCUR_COLR 1
+_ACEOF
+
+  LIBS="-lcur_colr $LIBS"
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking for main in -lintl" >&5
+echo $ECHO_N "checking for main in -lintl... $ECHO_C" >&6
+if test "${ac_cv_lib_intl_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_intl_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_intl_main=no
+fi
+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_intl_main" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_main" >&6
+if test $ac_cv_lib_intl_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBINTL 1
+_ACEOF
+
+  LIBS="-lintl $LIBS"
+
+fi
+
+
+case "$target" in
+    *sgi-irix*)
+
+echo "$as_me:$LINENO: checking for main in -lsocket" >&5
+echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_socket_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_main=no
+fi
+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_socket_main" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_main" >&6
+if test $ac_cv_lib_socket_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSOCKET 1
+_ACEOF
+
+  LIBS="-lsocket $LIBS"
+
+fi
+
+                       ;;
+    *)
+
+echo "$as_me:$LINENO: checking for main in -lnsl" >&5
+echo $ECHO_N "checking for main in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_nsl_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_main=no
+fi
+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_nsl_main" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_main" >&6
+if test $ac_cv_lib_nsl_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNSL 1
+_ACEOF
+
+  LIBS="-lnsl $LIBS"
+
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lsocket" >&5
+echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_socket_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_main=no
+fi
+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_socket_main" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_main" >&6
+if test $ac_cv_lib_socket_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSOCKET 1
+_ACEOF
+
+  LIBS="-lsocket $LIBS"
+
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lsun" >&5
+echo $ECHO_N "checking for main in -lsun... $ECHO_C" >&6
+if test "${ac_cv_lib_sun_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsun  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_sun_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sun_main=no
+fi
+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_sun_main" >&5
+echo "${ECHO_T}$ac_cv_lib_sun_main" >&6
+if test $ac_cv_lib_sun_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSUN 1
+_ACEOF
+
+  LIBS="-lsun $LIBS"
+
+fi
+
+                       ;;
+esac
+
+
+echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
+echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6
+if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ltermcap  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  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
+  ac_cv_lib_termcap_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_termcap_tgetent=no
+fi
+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_termcap_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6
+if test $ac_cv_lib_termcap_tgetent = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBTERMCAP 1
+_ACEOF
+
+  LIBS="-ltermcap $LIBS"
+
+fi
+
+if test "$ac_cv_lib_termcap_tgetent" != yes; then
+
+echo "$as_me:$LINENO: checking for tgetent in -lcurses" >&5
+echo $ECHO_N "checking for tgetent in -lcurses... $ECHO_C" >&6
+if test "${ac_cv_lib_curses_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  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
+  ac_cv_lib_curses_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_curses_tgetent=no
+fi
+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_curses_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_curses_tgetent" >&6
+if test $ac_cv_lib_curses_tgetent = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+  LIBS="-lcurses $LIBS"
+
+fi
+
+    if test "$ac_cv_lib_curses_tgetent" != yes; then
+
+echo "$as_me:$LINENO: checking for tgetent in -lncurses" >&5
+echo $ECHO_N "checking for tgetent in -lncurses... $ECHO_C" >&6
+if test "${ac_cv_lib_ncurses_tgetent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 tgetent ();
+int
+main ()
+{
+tgetent ();
+  ;
+  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
+  ac_cv_lib_ncurses_tgetent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ncurses_tgetent=no
+fi
+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_ncurses_tgetent" >&5
+echo "${ECHO_T}$ac_cv_lib_ncurses_tgetent" >&6
+if test $ac_cv_lib_ncurses_tgetent = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNCURSES 1
+_ACEOF
+
+  LIBS="-lncurses $LIBS"
+
+fi
+
+    fi
+fi
+if test "$ac_cv_lib_termcap_tgetent" = yes ||
+   test "$ac_cv_lib_curses_tgetent" = yes ||
+   test "$ac_cv_lib_ncurses_tgetent" = yes; then
+
+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
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 readline ();
+int
+main ()
+{
+readline ();
+  ;
+  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
+  ac_cv_lib_readline_readline=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_readline_readline=no
+fi
+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_readline_readline" >&5
+echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6
+if test $ac_cv_lib_readline_readline = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBREADLINE 1
+_ACEOF
+
+  LIBS="-lreadline $LIBS"
+
+fi
+
+    if test "$ac_cv_lib_readline_readline" != yes; then
+       { 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
+else
+    { echo "$as_me:$LINENO: WARNING: *** No terminal library, no history and command line editing in amrecover!" >&5
+echo "$as_me: WARNING: *** No terminal library, no history and command line editing in amrecover!" >&2;}
+fi
+
+if test "$ac_cv_lib_readline_readline" = yes; then
+    READLINE_LIBS=-lreadline
+    LIBS=`echo $LIBS | sed s/-lreadline//`
+
+fi
+
+if test "$ac_cv_header_linux_zftape_h" = yes; then
+    if test "$ac_cv_header_vtblc_h" = yes; then
+
+echo "$as_me:$LINENO: checking for main in -lvtblc" >&5
+echo $ECHO_N "checking for main in -lvtblc... $ECHO_C" >&6
+if test "${ac_cv_lib_vtblc_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lvtblc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_vtblc_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_vtblc_main=no
+fi
+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_vtblc_main" >&5
+echo "${ECHO_T}$ac_cv_lib_vtblc_main" >&6
+if test $ac_cv_lib_vtblc_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBVTBLC 1
+_ACEOF
+
+  LIBS="-lvtblc $LIBS"
+
+fi
+
+        if test "$ac_cv_lib_vtblc_main" != yes; then
+            { echo "$as_me:$LINENO: WARNING: *** vtblc library not found - no QIC volume table support!" >&5
+echo "$as_me: WARNING: *** vtblc library not found - no QIC volume table support!" >&2;}
+        fi
+    else
+        { echo "$as_me:$LINENO: WARNING: *** vtblc headers not found - no QIC volume table support!" >&5
+echo "$as_me: WARNING: *** vtblc headers not found - no QIC volume table support!" >&2;}
+    fi
+fi
+
+
+echo "$as_me:$LINENO: checking for modf in -lm" >&5
+echo $ECHO_N "checking for modf in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_modf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 modf ();
+int
+main ()
+{
+modf ();
+  ;
+  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
+  ac_cv_lib_m_modf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_modf=no
+fi
+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_m_modf" >&5
+echo "${ECHO_T}$ac_cv_lib_m_modf" >&6
+if test $ac_cv_lib_m_modf = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBM 1
+_ACEOF
+
+  LIBS="-lm $LIBS"
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking for mt_flags mtget structure element" >&5
+echo $ECHO_N "checking for mt_flags mtget structure element... $ECHO_C" >&6
+mt_flags_result="found"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_flags;
+
+  ;
+  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
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MT_FLAGS 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+mt_flags_result="not found"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $mt_flags_result" >&5
+echo "${ECHO_T}$mt_flags_result" >&6
+
+echo "$as_me:$LINENO: checking for mt_fileno mtget structure element" >&5
+echo $ECHO_N "checking for mt_fileno mtget structure element... $ECHO_C" >&6
+mt_fileno_result="found"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_fileno;
+
+  ;
+  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
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MT_FILENO 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+mt_fileno_result="not found"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $mt_fileno_result" >&5
+echo "${ECHO_T}$mt_fileno_result" >&6
+
+echo "$as_me:$LINENO: checking for mt_blkno mtget structure element" >&5
+echo $ECHO_N "checking for mt_blkno mtget structure element... $ECHO_C" >&6
+mt_blkno_result="found"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_blkno;
+
+  ;
+  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
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MT_BLKNO 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+mt_blkno_result="not found"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $mt_blkno_result" >&5
+echo "${ECHO_T}$mt_blkno_result" >&6
+
+echo "$as_me:$LINENO: checking for mt_dsreg mtget structure element" >&5
+echo $ECHO_N "checking for mt_dsreg mtget structure element... $ECHO_C" >&6
+mt_dsreg_result="found"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_dsreg;
+
+  ;
+  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
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MT_DSREG 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+mt_dsreg_result="not found"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $mt_dsreg_result" >&5
+echo "${ECHO_T}$mt_dsreg_result" >&6
+
+echo "$as_me:$LINENO: checking for mt_erreg mtget structure element" >&5
+echo $ECHO_N "checking for mt_erreg mtget structure element... $ECHO_C" >&6
+mt_erreg_result="found"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+
+int
+main ()
+{
+
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_erreg;
+
+  ;
+  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
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MT_ERREG 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+mt_erreg_result="not found"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $mt_erreg_result" >&5
+echo "${ECHO_T}$mt_erreg_result" >&6
+
+
+DB_HEADER=
+DB_LIB=
+
+save_LIBS="$LIBS"
+
+echo "$as_me:$LINENO: checking for dbm_open in -lc" >&5
+echo $ECHO_N "checking for dbm_open in -lc... $ECHO_C" >&6
+if test "${ac_cv_lib_c_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  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
+  ac_cv_lib_c_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_c_dbm_open=no
+fi
+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_c_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_c_dbm_open" >&6
+if test $ac_cv_lib_c_dbm_open = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBC 1
+_ACEOF
+
+  LIBS="-lc $LIBS"
+
+fi
+
+LIBS="$save_LIBS"
+
+case "$DB_STYLE" in
+    db)
+       if test "$ac_cv_header_db_h" = yes; then
+
+echo "$as_me:$LINENO: checking for main in -ldb" >&5
+echo $ECHO_N "checking for main in -ldb... $ECHO_C" >&6
+if test "${ac_cv_lib_db_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldb  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_db_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_db_main=no
+fi
+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_db_main" >&5
+echo "${ECHO_T}$ac_cv_lib_db_main" >&6
+if test $ac_cv_lib_db_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDB 1
+_ACEOF
+
+  LIBS="-ldb $LIBS"
+
+fi
+
+           if test "$ac_cv_lib_db_main" = yes; then
+
+echo "$as_me:$LINENO: checking for dbm_open in -ldb" >&5
+echo $ECHO_N "checking for dbm_open in -ldb... $ECHO_C" >&6
+if test "${ac_cv_lib_db_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldb  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  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
+  ac_cv_lib_db_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_db_dbm_open=no
+fi
+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_db_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_db_dbm_open" >&6
+if test $ac_cv_lib_db_dbm_open = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDB 1
+_ACEOF
+
+  LIBS="-ldb $LIBS"
+
+fi
+
+               if test "$ac_cv_lib_db_dbm_open" = yes; then
+                   DB_HEADER=db.h
+                   DB_LIB=db
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** db database library requested but dbm_open not found in -ldb." >&5
+echo "$as_me: WARNING: *** db database library requested but dbm_open not found in -ldb." >&2;}
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=db.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** db library requested but -ldb doesn't exist and dbm_open cannot be found." >&5
+echo "$as_me: WARNING: *** db library requested but -ldb doesn't exist and dbm_open cannot be found." >&2;}
+               fi
+           fi
+       else
+           DB_STYLE=
+           { echo "$as_me:$LINENO: WARNING: *** db database library requested but db.h not found." >&5
+echo "$as_me: WARNING: *** db database library requested but db.h not found." >&2;}
+       fi
+       ;;
+
+    dbm)
+       if test "$ac_cv_header_dbm_h" = yes; then
+
+echo "$as_me:$LINENO: checking for main in -ldbm" >&5
+echo $ECHO_N "checking for main in -ldbm... $ECHO_C" >&6
+if test "${ac_cv_lib_dbm_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_dbm_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dbm_main=no
+fi
+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_dbm_main" >&5
+echo "${ECHO_T}$ac_cv_lib_dbm_main" >&6
+if test $ac_cv_lib_dbm_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDBM 1
+_ACEOF
+
+  LIBS="-ldbm $LIBS"
+
+fi
+
+           if test "$ac_cv_lib_dbm_main" = yes; then
+
+echo "$as_me:$LINENO: checking for dbm_open in -ldbm" >&5
+echo $ECHO_N "checking for dbm_open in -ldbm... $ECHO_C" >&6
+if test "${ac_cv_lib_dbm_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  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
+  ac_cv_lib_dbm_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dbm_dbm_open=no
+fi
+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_dbm_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_dbm_dbm_open" >&6
+if test $ac_cv_lib_dbm_dbm_open = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDBM 1
+_ACEOF
+
+  LIBS="-ldbm $LIBS"
+
+fi
+
+               if test "$ac_cv_lib_dbm_dbm_open" = yes; then
+                   DB_HEADER=dbm.h
+                   DB_LIB=dbm
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** dbm database library requested but dbm_open not found in -ldbm." >&5
+echo "$as_me: WARNING: *** dbm database library requested but dbm_open not found in -ldbm." >&2;}
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=dbm.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** dbm library requested but -ldbm doesn't exist and dbm_open cannot be found." >&5
+echo "$as_me: WARNING: *** dbm library requested but -ldbm doesn't exist and dbm_open cannot be found." >&2;}
+               fi
+           fi
+       else
+           DB_STYLE=
+           { echo "$as_me:$LINENO: WARNING: *** dbm database library requested but dbm.h not found." >&5
+echo "$as_me: WARNING: *** dbm database library requested but dbm.h not found." >&2;}
+       fi
+       ;;
+
+    gdbm)
+       if test "$ac_cv_header_ndbm_h" = yes; then
+
+echo "$as_me:$LINENO: checking for main in -lgdbm" >&5
+echo $ECHO_N "checking for main in -lgdbm... $ECHO_C" >&6
+if test "${ac_cv_lib_gdbm_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_gdbm_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gdbm_main=no
+fi
+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_gdbm_main" >&5
+echo "${ECHO_T}$ac_cv_lib_gdbm_main" >&6
+if test $ac_cv_lib_gdbm_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGDBM 1
+_ACEOF
+
+  LIBS="-lgdbm $LIBS"
+
+fi
+
+           if test "$ac_cv_lib_gdbm_main" = yes; then
+
+echo "$as_me:$LINENO: checking for dbm_open in -lgdbm" >&5
+echo $ECHO_N "checking for dbm_open in -lgdbm... $ECHO_C" >&6
+if test "${ac_cv_lib_gdbm_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  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
+  ac_cv_lib_gdbm_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gdbm_dbm_open=no
+fi
+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_gdbm_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_gdbm_dbm_open" >&6
+if test $ac_cv_lib_gdbm_dbm_open = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGDBM 1
+_ACEOF
+
+  LIBS="-lgdbm $LIBS"
+
+fi
+
+               if test "$ac_cv_lib_gdbm_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=gdbm
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** gdbm database library requested but -lgdbm not found." >&5
+echo "$as_me: WARNING: *** gdbm database library requested but -lgdbm not found." >&2;}
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** gdbm library requested but -lgdbm doesn't exist and dbm_open cannot be found." >&5
+echo "$as_me: WARNING: *** gdbm library requested but -lgdbm doesn't exist and dbm_open cannot be found." >&2;}
+               fi
+           fi
+       else
+           DB_STYLE=
+           { echo "$as_me:$LINENO: WARNING: *** gdbm database library requested but ndbm.h not found." >&5
+echo "$as_me: WARNING: *** gdbm database library requested but ndbm.h not found." >&2;}
+       fi
+       ;;
+
+    ndbm)
+       if test "$ac_cv_header_ndbm_h" = yes; then
+
+echo "$as_me:$LINENO: checking for main in -lndbm" >&5
+echo $ECHO_N "checking for main in -lndbm... $ECHO_C" >&6
+if test "${ac_cv_lib_ndbm_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lndbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  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
+  ac_cv_lib_ndbm_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ndbm_main=no
+fi
+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_ndbm_main" >&5
+echo "${ECHO_T}$ac_cv_lib_ndbm_main" >&6
+if test $ac_cv_lib_ndbm_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNDBM 1
+_ACEOF
+
+  LIBS="-lndbm $LIBS"
+
+fi
+
+           if test "$ac_cv_lib_ndbm_main" = yes; then
+
+echo "$as_me:$LINENO: checking for dbm_open in -lndbm" >&5
+echo $ECHO_N "checking for dbm_open in -lndbm... $ECHO_C" >&6
+if test "${ac_cv_lib_ndbm_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lndbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  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
+  ac_cv_lib_ndbm_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ndbm_dbm_open=no
+fi
+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_ndbm_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_ndbm_dbm_open" >&6
+if test $ac_cv_lib_ndbm_dbm_open = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBNDBM 1
+_ACEOF
+
+  LIBS="-lndbm $LIBS"
+
+fi
+
+               if test "$ac_cv_lib_ndbm_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=ndbm
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** ndbm database library requested but -lndbm not found." >&5
+echo "$as_me: WARNING: *** ndbm database library requested but -lndbm not found." >&2;}
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   { echo "$as_me:$LINENO: WARNING: *** ndbm library requested but -lndbm doesn't exist and dbm_open cannot be found." >&5
+echo "$as_me: WARNING: *** ndbm library requested but -lndbm doesn't exist and dbm_open cannot be found." >&2;}
+               fi
+           fi
+       else
+           DB_STYLE=
+           { echo "$as_me:$LINENO: WARNING: *** ndbm database library requested but ndbm.h not found." >&5
+echo "$as_me: WARNING: *** ndbm database library requested but ndbm.h not found." >&2;}
+       fi
+       ;;
+    text)
+       DB_HEADER=
+       DB_LIB=
+       ;;
+esac
+
+
+if test -z "$DB_STYLE"; then
+    DB_STYLE=text
+    DB_HEADER=
+    DB_LIB=
+fi
+
+
+if test "$DB_STYLE" = text; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TEXTDB 1
+_ACEOF
+
+else
+    echo "$as_me:$LINENO: checking for database" >&5
+echo $ECHO_N "checking for database... $ECHO_C" >&6
+    echo "$as_me:$LINENO: result: header is $DB_HEADER, linking against -l$DB_LIB" >&5
+echo "${ECHO_T}header is $DB_HEADER, linking against -l$DB_LIB" >&6
+    case "$DB_STYLE" in
+       db)
+cat >>confdefs.h <<\_ACEOF
+#define USE_DB_H 1
+_ACEOF
+   ;;
+       dbm)
+cat >>confdefs.h <<\_ACEOF
+#define USE_DBM_H 1
+_ACEOF
+  ;;
+       gdbm)
+cat >>confdefs.h <<\_ACEOF
+#define USE_GDBM_H 1
+_ACEOF
+ ;;
+       ndbm)
+cat >>confdefs.h <<\_ACEOF
+#define USE_NDBM_H 1
+_ACEOF
+ ;;
+    esac
+
+    echo "$as_me:$LINENO: checking for struct datum declared in header files" >&5
+echo $ECHO_N "checking for struct datum declared in header files... $ECHO_C" >&6
+if test "${amanda_cv_struct_datum+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.  */
+
+#if defined(USE_DB_H)
+#  include <db.h>
+#else
+#  if defined(USE_DBM_H)
+#    include <dbm.h>
+#  else
+#    if defined(USE_NDBM_H)
+#      include <ndbm.h>
+#    endif
+#  endif
+#endif
+
+int
+main ()
+{
+
+                   datum a;
+
+  ;
+  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_struct_datum=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+amanda_cv_struct_datum=no
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_struct_datum" >&5
+echo "${ECHO_T}$amanda_cv_struct_datum" >&6
+    if test "$amanda_cv_struct_datum" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_DATUM 1
+_ACEOF
+
+    fi
+fi
+
+case "$DB_STYLE" in
+    db) DB_EXT=.db;;
+    gdbm) DB_EXT='""';;
+    dbm | ndbm) DB_EXT=".dir .pag";;
+    text) DB_EXT='""';;
+    *) DB_EXT=;;
+esac
+
+
+echo "$as_me:$LINENO: checking whether _POSIX2_RE_DUP_MAX is defined" >&5
+echo $ECHO_N "checking whether _POSIX2_RE_DUP_MAX is defined... $ECHO_C" >&6
+if test "${amanda_cv_have__posix2_re_dup_max+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 <limits.h>
+#ifdef _POSIX2_RE_DUP_MAX
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  amanda_cv_have__posix2_re_dup_max=yes
+else
+  amanda_cv_have__posix2_re_dup_max=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_have__posix2_re_dup_max" >&5
+echo "${ECHO_T}$amanda_cv_have__posix2_re_dup_max" >&6
+if test "$amanda_cv_have__posix2_re_dup_max" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE__POSIX2_RE_DUP_MAX 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether CHAR_MIN is defined" >&5
+echo $ECHO_N "checking whether CHAR_MIN is defined... $ECHO_C" >&6
+if test "${amanda_cv_have_char_min+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 <limits.h>
+#ifdef CHAR_MIN
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  amanda_cv_have_char_min=yes
+else
+  amanda_cv_have_char_min=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_have_char_min" >&5
+echo "${ECHO_T}$amanda_cv_have_char_min" >&6
+if test "$amanda_cv_have_char_min" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CHAR_MIN 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether CHAR_MAX is defined" >&5
+echo $ECHO_N "checking whether CHAR_MAX is defined... $ECHO_C" >&6
+if test "${amanda_cv_have_char_max+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 <limits.h>
+#ifdef CHAR_MAX
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  amanda_cv_have_char_max=yes
+else
+  amanda_cv_have_char_max=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_have_char_max" >&5
+echo "${ECHO_T}$amanda_cv_have_char_max" >&6
+if test "$amanda_cv_have_char_max" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CHAR_MAX 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether CHAR_BIT is defined" >&5
+echo $ECHO_N "checking whether CHAR_BIT is defined... $ECHO_C" >&6
+if test "${amanda_cv_have_char_bit+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 <limits.h>
+#ifdef CHAR_BIT
+  yes
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then
+  amanda_cv_have_char_bit=yes
+else
+  amanda_cv_have_char_bit=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_have_char_bit" >&5
+echo "${ECHO_T}$amanda_cv_have_char_bit" >&6
+if test "$amanda_cv_have_char_bit" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_CHAR_BIT 1
+_ACEOF
+
+fi
+
+
+ice_have_accept=no
+
+for ac_func in accept
+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_accept=yes
+fi
+done
+
+if test "${ice_have_accept}" = yes; then
+echo "$as_me:$LINENO: checking for accept declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for accept declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_accept_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_accept_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}accept[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_accept_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_accept_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}accept[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_accept_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_accept_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_accept_decl" >&5
+echo "${ECHO_T}$ice_cv_have_accept_decl" >&6
+if test "$ice_cv_have_accept_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ACCEPT_DECL 1
+_ACEOF
+
+fi
+fi
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo "$as_me:$LINENO: checking for working alloca.h" >&5
+echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6
+if test "${ac_cv_working_alloca_h+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 <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+  ;
+  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
+  ac_cv_working_alloca_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_working_alloca_h=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5
+echo "${ECHO_T}$ac_cv_working_alloca_h" >&6
+if test $ac_cv_working_alloca_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for alloca" >&5
+echo $ECHO_N "checking for alloca... $ECHO_C" >&6
+if test "${ac_cv_func_alloca_works+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 __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+  ;
+  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
+  ac_cv_func_alloca_works=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_alloca_works=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5
+echo "${ECHO_T}$ac_cv_func_alloca_works" >&6
+
+if test $ac_cv_func_alloca_works = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALLOCA 1
+_ACEOF
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=alloca.$ac_objext
+
+cat >>confdefs.h <<\_ACEOF
+#define C_ALLOCA 1
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5
+echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6
+if test "${ac_cv_os_cray+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.  */
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5
+echo "${ECHO_T}$ac_cv_os_cray" >&6
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; 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 CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+echo "$as_me:$LINENO: checking stack direction for C alloca" >&5
+echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6
+if test "${ac_cv_c_stack_direction+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  exit (find_stack_direction () < 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_c_stack_direction=1
+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 )
+ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5
+echo "${ECHO_T}$ac_cv_c_stack_direction" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+
+for ac_func in atexit
+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
+
+fi
+done
+
+
+ice_have_atof=no
+
+for ac_func in atof
+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_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
+
+
+for ac_func in basename
+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
+
+fi
+done
+
+
+ice_have_bind=no
+
+for ac_func in bind
+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_bind=yes
+fi
+done
+
+if test "${ice_have_bind}" = yes; then
+echo "$as_me:$LINENO: checking for bind declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for bind declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_bind_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_bind_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}bind[  ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_bind_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_bind_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}bind[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_bind_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_bind_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_bind_decl" >&5
+echo "${ECHO_T}$ice_cv_have_bind_decl" >&6
+if test "$ice_cv_have_bind_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_BIND_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_bcopy=no
+
+for ac_func in bcopy
+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_bcopy=yes
+fi
+done
+
+if test "${ice_have_bcopy}" = yes; then
+echo "$as_me:$LINENO: checking for bcopy declaration in string.h strings.h stdlib.h" >&5
+echo $ECHO_N "checking for bcopy declaration in string.h strings.h stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_bcopy_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_bcopy_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in string.h strings.h 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}bcopy[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_bcopy_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_bcopy_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}bcopy[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_bcopy_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_bcopy_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_bcopy_decl" >&5
+echo "${ECHO_T}$ice_cv_have_bcopy_decl" >&6
+if test "$ice_cv_have_bcopy_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_BCOPY_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_bzero=no
+
+for ac_func in bzero
+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_bzero=yes
+fi
+done
+
+if test "${ice_have_bzero}" = yes; then
+echo "$as_me:$LINENO: checking for bzero declaration in string.h strings.h stdlib.h" >&5
+echo $ECHO_N "checking for bzero declaration in string.h strings.h stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_bzero_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_bzero_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in string.h strings.h 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}bzero[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_bzero_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_bzero_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}bzero[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_bzero_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_bzero_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_bzero_decl" >&5
+echo "${ECHO_T}$ice_cv_have_bzero_decl" >&6
+if test "$ice_cv_have_bzero_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_BZERO_DECL 1
+_ACEOF
+
+fi
+fi
+
+echo "$as_me:$LINENO: checking whether closedir returns void" >&5
+echo $ECHO_N "checking whether closedir returns void... $ECHO_C" >&6
+if test "${ac_cv_func_closedir_void+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_closedir_void=yes
+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_header_dirent>
+#ifndef __cplusplus
+int closedir ();
+#endif
+
+int
+main ()
+{
+exit (closedir (opendir (".")) != 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_func_closedir_void=no
+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 )
+ac_cv_func_closedir_void=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_closedir_void" >&5
+echo "${ECHO_T}$ac_cv_func_closedir_void" >&6
+if test $ac_cv_func_closedir_void = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define CLOSEDIR_VOID 1
+_ACEOF
+
+fi
+
+
+ice_have_closelog=no
+
+for ac_func in closelog
+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_closelog=yes
+fi
+done
+
+if test "${ice_have_closelog}" = yes; then
+echo "$as_me:$LINENO: checking for closelog declaration in syslog.h" >&5
+echo $ECHO_N "checking for closelog declaration in syslog.h... $ECHO_C" >&6
+if test "${ice_cv_have_closelog_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_closelog_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in syslog.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}closelog[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_closelog_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_closelog_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}closelog[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_closelog_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_closelog_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_closelog_decl" >&5
+echo "${ECHO_T}$ice_cv_have_closelog_decl" >&6
+if test "$ice_cv_have_closelog_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOSELOG_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_connect=no
+
+for ac_func in connect
+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_connect=yes
+fi
+done
+
+if test "${ice_have_connect}" = yes; then
+echo "$as_me:$LINENO: checking for connect declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for connect declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_connect_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_connect_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}connect[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_connect_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_connect_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}connect[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_connect_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_connect_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_connect_decl" >&5
+echo "${ECHO_T}$ice_cv_have_connect_decl" >&6
+if test "$ice_cv_have_connect_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CONNECT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_dbm_open=no
+
+for ac_func in dbm_open
+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_dbm_open=yes
+fi
+done
+
+if test "${ice_have_dbm_open}" = yes; then
+echo "$as_me:$LINENO: checking for dbm_open declaration in ${DB_HEADER-no/db/header/file}" >&5
+echo $ECHO_N "checking for dbm_open declaration in ${DB_HEADER-no/db/header/file}... $ECHO_C" >&6
+if test "${ice_cv_have_dbm_open_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_dbm_open_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in ${DB_HEADER-no/db/header/file}; 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}dbm_open[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_dbm_open_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_dbm_open_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}dbm_open[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_dbm_open_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_dbm_open_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_dbm_open_decl" >&5
+echo "${ECHO_T}$ice_cv_have_dbm_open_decl" >&6
+if test "$ice_cv_have_dbm_open_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DBM_OPEN_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in endmntent
+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
+
+fi
+done
+
+
+ice_have_fclose=no
+
+for ac_func in fclose
+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_fclose=yes
+fi
+done
+
+if test "${ice_have_fclose}" = yes; then
+echo "$as_me:$LINENO: checking for fclose declaration in stdio.h" >&5
+echo $ECHO_N "checking for fclose declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_fclose_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fclose_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}fclose[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fclose_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fclose_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}fclose[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fclose_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fclose_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fclose_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fclose_decl" >&6
+if test "$ice_cv_have_fclose_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FCLOSE_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_fflush=no
+
+for ac_func in fflush
+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_fflush=yes
+fi
+done
+
+if test "${ice_have_fflush}" = yes; then
+echo "$as_me:$LINENO: checking for fflush declaration in stdio.h" >&5
+echo $ECHO_N "checking for fflush declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_fflush_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fflush_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}fflush[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fflush_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fflush_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}fflush[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fflush_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fflush_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fflush_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fflush_decl" >&6
+if test "$ice_cv_have_fflush_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FFLUSH_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_flock=no
+
+for ac_func in flock
+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_flock=yes
+fi
+done
+
+if test "${ice_have_flock}" = yes; then
+echo "$as_me:$LINENO: checking for flock declaration in sys/file.h" >&5
+echo $ECHO_N "checking for flock declaration in sys/file.h... $ECHO_C" >&6
+if test "${ice_cv_have_flock_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_flock_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/file.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}flock[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_flock_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_flock_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}flock[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_flock_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_flock_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_flock_decl" >&5
+echo "${ECHO_T}$ice_cv_have_flock_decl" >&6
+if test "$ice_cv_have_flock_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOCK_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_fprintf=no
+
+for ac_func in fprintf
+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_fprintf=yes
+fi
+done
+
+if test "${ice_have_fprintf}" = yes; then
+echo "$as_me:$LINENO: checking for fprintf declaration in stdio.h" >&5
+echo $ECHO_N "checking for fprintf declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_fprintf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fprintf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}fprintf[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fprintf_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}fprintf[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fprintf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fprintf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fprintf_decl" >&6
+if test "$ice_cv_have_fprintf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FPRINTF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_fputc=no
+
+for ac_func in fputc
+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_fputc=yes
+fi
+done
+
+if test "${ice_have_fputc}" = yes; then
+echo "$as_me:$LINENO: checking for fputc declaration in stdio.h" >&5
+echo $ECHO_N "checking for fputc declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_fputc_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fputc_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}fputc[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fputc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fputc_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}fputc[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fputc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fputc_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fputc_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fputc_decl" >&6
+if test "$ice_cv_have_fputc_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FPUTC_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_fputs=no
+
+for ac_func in fputs
+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_fputs=yes
+fi
+done
+
+if test "${ice_have_fputs}" = yes; then
+echo "$as_me:$LINENO: checking for fputs declaration in stdio.h" >&5
+echo $ECHO_N "checking for fputs declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_fputs_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fputs_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}fputs[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fputs_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fputs_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}fputs[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fputs_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fputs_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fputs_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fputs_decl" >&6
+if test "$ice_cv_have_fputs_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FPUTS_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_fread=no
+
+for ac_func in fread
+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_fread=yes
+fi
+done
+
+if test "${ice_have_fread}" = yes; then
+echo "$as_me:$LINENO: checking for fread declaration in stdio.h stdlib.h" >&5
+echo $ECHO_N "checking for fread declaration in stdio.h stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_fread_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fread_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.h 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}fread[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fread_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fread_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}fread[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fread_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fread_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fread_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fread_decl" >&6
+if test "$ice_cv_have_fread_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FREAD_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_fseek=no
+
+for ac_func in fseek
+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_fseek=yes
+fi
+done
+
+if test "${ice_have_fseek}" = yes; then
+echo "$as_me:$LINENO: checking for fseek declaration in stdio.h" >&5
+echo $ECHO_N "checking for fseek declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_fseek_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fseek_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}fseek[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fseek_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fseek_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}fseek[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fseek_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fseek_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fseek_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fseek_decl" >&6
+if test "$ice_cv_have_fseek_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FSEEK_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_fwrite=no
+
+for ac_func in fwrite
+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_fwrite=yes
+fi
+done
+
+if test "${ice_have_fwrite}" = yes; then
+echo "$as_me:$LINENO: checking for fwrite declaration in stdio.h stdlib.h" >&5
+echo $ECHO_N "checking for fwrite declaration in stdio.h stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_fwrite_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_fwrite_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.h 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}fwrite[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_fwrite_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fwrite_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}fwrite[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_fwrite_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_fwrite_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_fwrite_decl" >&5
+echo "${ECHO_T}$ice_cv_have_fwrite_decl" >&6
+if test "$ice_cv_have_fwrite_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FWRITE_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in getcwd
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+for ac_func in getfsent
+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
+
+fi
+done
+
+
+ice_have_gethostname=no
+
+for ac_func in gethostname
+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_gethostname=yes
+fi
+done
+
+if test "${ice_have_gethostname}" = yes; then
+echo "$as_me:$LINENO: checking for gethostname declaration in unistd.h" >&5
+echo $ECHO_N "checking for gethostname declaration in unistd.h... $ECHO_C" >&6
+if test "${ice_cv_have_gethostname_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_gethostname_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in unistd.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}gethostname[   ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_gethostname_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_gethostname_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}gethostname[   ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_gethostname_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_gethostname_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_gethostname_decl" >&5
+echo "${ECHO_T}$ice_cv_have_gethostname_decl" >&6
+if test "$ice_cv_have_gethostname_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GETHOSTNAME_DECL 1
+_ACEOF
+
+fi
+fi
+
+# getmntent is in -lsun on Irix 4, -lseq on Dynix/PTX, -lgen on Unixware.
+echo "$as_me:$LINENO: checking for getmntent in -lsun" >&5
+echo $ECHO_N "checking for getmntent in -lsun... $ECHO_C" >&6
+if test "${ac_cv_lib_sun_getmntent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsun  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 getmntent ();
+int
+main ()
+{
+getmntent ();
+  ;
+  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
+  ac_cv_lib_sun_getmntent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sun_getmntent=no
+fi
+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_sun_getmntent" >&5
+echo "${ECHO_T}$ac_cv_lib_sun_getmntent" >&6
+if test $ac_cv_lib_sun_getmntent = yes; then
+  LIBS="-lsun $LIBS"
+else
+  echo "$as_me:$LINENO: checking for getmntent in -lseq" >&5
+echo $ECHO_N "checking for getmntent in -lseq... $ECHO_C" >&6
+if test "${ac_cv_lib_seq_getmntent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lseq  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 getmntent ();
+int
+main ()
+{
+getmntent ();
+  ;
+  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
+  ac_cv_lib_seq_getmntent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_seq_getmntent=no
+fi
+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_seq_getmntent" >&5
+echo "${ECHO_T}$ac_cv_lib_seq_getmntent" >&6
+if test $ac_cv_lib_seq_getmntent = yes; then
+  LIBS="-lseq $LIBS"
+else
+  echo "$as_me:$LINENO: checking for getmntent in -lgen" >&5
+echo $ECHO_N "checking for getmntent in -lgen... $ECHO_C" >&6
+if test "${ac_cv_lib_gen_getmntent+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgen  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 getmntent ();
+int
+main ()
+{
+getmntent ();
+  ;
+  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
+  ac_cv_lib_gen_getmntent=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gen_getmntent=no
+fi
+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_gen_getmntent" >&5
+echo "${ECHO_T}$ac_cv_lib_gen_getmntent" >&6
+if test $ac_cv_lib_gen_getmntent = yes; then
+  LIBS="-lgen $LIBS"
+fi
+
+fi
+
+fi
+
+
+for ac_func in getmntent
+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
+
+fi
+done
+
+
+
+ice_have_getopt=no
+
+for ac_func in getopt
+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_getopt=yes
+fi
+done
+
+if test "${ice_have_getopt}" = yes; then
+echo "$as_me:$LINENO: checking for getopt declaration in stdlib.h unistd.h libc.h" >&5
+echo $ECHO_N "checking for getopt declaration in stdlib.h unistd.h libc.h... $ECHO_C" >&6
+if test "${ice_cv_have_getopt_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_getopt_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdlib.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}getopt[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_getopt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getopt_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}getopt[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_getopt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getopt_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_getopt_decl" >&5
+echo "${ECHO_T}$ice_cv_have_getopt_decl" >&6
+if test "$ice_cv_have_getopt_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GETOPT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_getpeername=no
+
+for ac_func in getpeername
+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_getpeername=yes
+fi
+done
+
+if test "${ice_have_getpeername}" = yes; then
+echo "$as_me:$LINENO: checking for getpeername declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for getpeername declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_getpeername_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_getpeername_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}getpeername[   ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_getpeername_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getpeername_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}getpeername[   ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_getpeername_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getpeername_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_getpeername_decl" >&5
+echo "${ECHO_T}$ice_cv_have_getpeername_decl" >&6
+if test "$ice_cv_have_getpeername_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GETPEERNAME_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in getpgrp
+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
+
+fi
+done
+
+echo "$as_me:$LINENO: checking whether getpgrp requires zero arguments" >&5
+echo $ECHO_N "checking whether getpgrp requires zero arguments... $ECHO_C" >&6
+if test "${ac_cv_func_getpgrp_void+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Use it with a single arg.
+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 ()
+{
+getpgrp (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_func_getpgrp_void=no
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getpgrp_void=yes
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getpgrp_void" >&5
+echo "${ECHO_T}$ac_cv_func_getpgrp_void" >&6
+if test $ac_cv_func_getpgrp_void = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GETPGRP_VOID 1
+_ACEOF
+
+fi
+
+
+ice_have_getsockname=no
+
+for ac_func in getsockname
+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_getsockname=yes
+fi
+done
+
+if test "${ice_have_getsockname}" = yes; then
+echo "$as_me:$LINENO: checking for getsockname declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for getsockname declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_getsockname_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_getsockname_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}getsockname[   ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_getsockname_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getsockname_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}getsockname[   ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_getsockname_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getsockname_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_getsockname_decl" >&5
+echo "${ECHO_T}$ice_cv_have_getsockname_decl" >&6
+if test "$ice_cv_have_getsockname_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GETSOCKNAME_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_getsockopt=no
+
+for ac_func in getsockopt
+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_getsockopt=yes
+fi
+done
+
+if test "${ice_have_getsockopt}" = yes; then
+echo "$as_me:$LINENO: checking for getsockopt declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for getsockopt declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_getsockopt_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_getsockopt_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}getsockopt[    ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_getsockopt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getsockopt_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}getsockopt[    ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_getsockopt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_getsockopt_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_getsockopt_decl" >&5
+echo "${ECHO_T}$ice_cv_have_getsockopt_decl" >&6
+if test "$ice_cv_have_getsockopt_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GETSOCKOPT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_gettimeofday=no
+
+for ac_func in gettimeofday
+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_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
+
+fi
+done
+
+
+ice_have_initgroups=no
+
+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
+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_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
+
+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
+
+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
+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_ioctl=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
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+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 sys/ioctl.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}ioctl[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_ioctl_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_ioctl_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}ioctl[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_ioctl_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_ioctl_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
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_IOCTL_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_listen=no
+
+for ac_func in listen
+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_listen=yes
+fi
+done
+
+if test "${ice_have_listen}" = yes; then
+echo "$as_me:$LINENO: checking for listen declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for listen declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_listen_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_listen_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}listen[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_listen_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_listen_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}listen[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_listen_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_listen_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_listen_decl" >&5
+echo "${ECHO_T}$ice_cv_have_listen_decl" >&6
+if test "$ice_cv_have_listen_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LISTEN_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_lstat=no
+
+for ac_func in lstat
+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_lstat=yes
+fi
+done
+
+if test "${ice_have_lstat}" = yes; then
+echo "$as_me:$LINENO: checking for lstat declaration in sys/types.h sys/stat.h" >&5
+echo $ECHO_N "checking for lstat declaration in sys/types.h sys/stat.h... $ECHO_C" >&6
+if test "${ice_cv_have_lstat_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_lstat_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/stat.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}lstat[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_lstat_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_lstat_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}lstat[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_lstat_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_lstat_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_lstat_decl" >&5
+echo "${ECHO_T}$ice_cv_have_lstat_decl" >&6
+if test "$ice_cv_have_lstat_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LSTAT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_malloc=no
+
+for ac_func in malloc
+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_malloc=yes
+fi
+done
+
+if test "${ice_have_malloc}" = yes; then
+echo "$as_me:$LINENO: checking for malloc declaration in stdlib.h" >&5
+echo $ECHO_N "checking for malloc declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_malloc_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_malloc_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}malloc[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_malloc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_malloc_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}malloc[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_malloc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_malloc_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_malloc_decl" >&5
+echo "${ECHO_T}$ice_cv_have_malloc_decl" >&6
+if test "$ice_cv_have_malloc_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MALLOC_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in memmove
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+ice_have_memmove=no
+
+for ac_func in memmove
+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_memmove=yes
+fi
+done
+
+if test "${ice_have_memmove}" = yes; then
+echo "$as_me:$LINENO: checking for memmove declaration in string.h strings.h" >&5
+echo $ECHO_N "checking for memmove declaration in string.h strings.h... $ECHO_C" >&6
+if test "${ice_cv_have_memmove_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_memmove_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in string.h strings.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}memmove[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_memmove_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_memmove_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}memmove[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_memmove_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_memmove_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_memmove_decl" >&5
+echo "${ECHO_T}$ice_cv_have_memmove_decl" >&6
+if test "$ice_cv_have_memmove_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MEMMOVE_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_memset=no
+
+for ac_func in memset
+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_memset=yes
+fi
+done
+
+if test "${ice_have_memset}" = yes; then
+echo "$as_me:$LINENO: checking for memset declaration in string.h strings.h" >&5
+echo $ECHO_N "checking for memset declaration in string.h strings.h... $ECHO_C" >&6
+if test "${ice_cv_have_memset_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_memset_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in string.h strings.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}memset[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_memset_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_memset_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}memset[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_memset_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_memset_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_memset_decl" >&5
+echo "${ECHO_T}$ice_cv_have_memset_decl" >&6
+if test "$ice_cv_have_memset_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MEMSET_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in mkdir
+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
+
+fi
+done
+
+
+ice_have_mktemp=no
+
+for ac_func in mktemp
+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_mktemp=yes
+fi
+done
+
+if test "${ice_have_mktemp}" = yes; then
+echo "$as_me:$LINENO: checking for mktemp declaration in stdlib.h" >&5
+echo $ECHO_N "checking for mktemp declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_mktemp_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_mktemp_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}mktemp[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_mktemp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_mktemp_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}mktemp[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_mktemp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_mktemp_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_mktemp_decl" >&5
+echo "${ECHO_T}$ice_cv_have_mktemp_decl" >&6
+if test "$ice_cv_have_mktemp_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MKTEMP_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in mktime
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+ice_have_mktime=no
+
+for ac_func in mktime
+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_mktime=yes
+fi
+done
+
+if test "${ice_have_mktime}" = yes; then
+echo "$as_me:$LINENO: checking for mktime declaration in time.h sys/time.h" >&5
+echo $ECHO_N "checking for mktime declaration in time.h sys/time.h... $ECHO_C" >&6
+if test "${ice_cv_have_mktime_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_mktime_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}mktime[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_mktime_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_mktime_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}mktime[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_mktime_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_mktime_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_mktime_decl" >&5
+echo "${ECHO_T}$ice_cv_have_mktime_decl" >&6
+if test "$ice_cv_have_mktime_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_MKTIME_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+for ac_header in stdlib.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+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_header>
+_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_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_func in getpagesize
+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
+
+fi
+done
+
+echo "$as_me:$LINENO: checking for working mmap" >&5
+echo $ECHO_N "checking for working mmap... $ECHO_C" >&6
+if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_mmap_fixed_mapped=no
+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
+/* malloc might have been renamed as rpl_malloc. */
+#undef malloc
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+   Here is a matrix of mmap possibilities:
+       mmap private not fixed
+       mmap private fixed at somewhere currently unmapped
+       mmap private fixed at somewhere already mapped
+       mmap shared not fixed
+       mmap shared fixed at somewhere currently unmapped
+       mmap shared fixed at somewhere already mapped
+   For private mappings, we should verify that changes cannot be read()
+   back from the file, nor mmap's back from the file at a different
+   address.  (There have been systems where private was not correctly
+   implemented like the infamous i386 svr4.0, and systems where the
+   VM page cache was not coherent with the file system buffer cache
+   like early versions of FreeBSD and possibly contemporary NetBSD.)
+   For shared mappings, we should conversely verify that changes get
+   propagated back to all the places they're supposed to be.
+
+   Grep wants private fixed already mapped.
+   The main things grep needs to know about mmap are:
+   * does it exist and is it safe to write into the mmap'd area
+   * how to use it (BSD variants)  */
+
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#if !STDC_HEADERS && !HAVE_STDLIB_H
+char *malloc ();
+#endif
+
+/* This mess was copied from the GNU getpagesize.h.  */
+#if !HAVE_GETPAGESIZE
+/* Assume that all systems that can run configure have sys/param.h.  */
+# if !HAVE_SYS_PARAM_H
+#  define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+#  define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+#  if HAVE_SYS_PARAM_H
+#   include <sys/param.h>
+#   ifdef EXEC_PAGESIZE
+#    define getpagesize() EXEC_PAGESIZE
+#   else /* no EXEC_PAGESIZE */
+#    ifdef NBPG
+#     define getpagesize() NBPG * CLSIZE
+#     ifndef CLSIZE
+#      define CLSIZE 1
+#     endif /* no CLSIZE */
+#    else /* no NBPG */
+#     ifdef NBPC
+#      define getpagesize() NBPC
+#     else /* no NBPC */
+#      ifdef PAGESIZE
+#       define getpagesize() PAGESIZE
+#      endif /* PAGESIZE */
+#     endif /* no NBPC */
+#    endif /* no NBPG */
+#   endif /* no EXEC_PAGESIZE */
+#  else /* no HAVE_SYS_PARAM_H */
+#   define getpagesize() 8192  /* punt totally */
+#  endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+int
+main ()
+{
+  char *data, *data2, *data3;
+  int i, pagesize;
+  int fd;
+
+  pagesize = getpagesize ();
+
+  /* First, make a file with some known garbage in it. */
+  data = (char *) malloc (pagesize);
+  if (!data)
+    exit (1);
+  for (i = 0; i < pagesize; ++i)
+    *(data + i) = rand ();
+  umask (0);
+  fd = creat ("conftest.mmap", 0600);
+  if (fd < 0)
+    exit (1);
+  if (write (fd, data, pagesize) != pagesize)
+    exit (1);
+  close (fd);
+
+  /* Next, try to mmap the file at a fixed address which already has
+     something else allocated at it.  If we can, also make sure that
+     we see the same garbage.  */
+  fd = open ("conftest.mmap", O_RDWR);
+  if (fd < 0)
+    exit (1);
+  data2 = (char *) malloc (2 * pagesize);
+  if (!data2)
+    exit (1);
+  data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1);
+  if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
+                    MAP_PRIVATE | MAP_FIXED, fd, 0L))
+    exit (1);
+  for (i = 0; i < pagesize; ++i)
+    if (*(data + i) != *(data2 + i))
+      exit (1);
+
+  /* Finally, make sure that changes to the mapped area do not
+     percolate back to the file as seen by read().  (This is a bug on
+     some variants of i386 svr4.0.)  */
+  for (i = 0; i < pagesize; ++i)
+    *(data2 + i) = *(data2 + i) + 1;
+  data3 = (char *) malloc (pagesize);
+  if (!data3)
+    exit (1);
+  if (read (fd, data3, pagesize) != pagesize)
+    exit (1);
+  for (i = 0; i < pagesize; ++i)
+    if (*(data + i) != *(data3 + i))
+      exit (1);
+  close (fd);
+  exit (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_func_mmap_fixed_mapped=yes
+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 )
+ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5
+echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MMAP 1
+_ACEOF
+
+fi
+rm -f conftest.mmap
+
+
+for ac_func in on_exit
+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
+
+fi
+done
+
+
+ice_have_openlog=no
+
+for ac_func in openlog
+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_openlog=yes
+fi
+done
+
+if test "${ice_have_openlog}" = yes; then
+echo "$as_me:$LINENO: checking for openlog declaration in syslog.h" >&5
+echo $ECHO_N "checking for openlog declaration in syslog.h... $ECHO_C" >&6
+if test "${ice_cv_have_openlog_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_openlog_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in syslog.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}openlog[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_openlog_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_openlog_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}openlog[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_openlog_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_openlog_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_openlog_decl" >&5
+echo "${ECHO_T}$ice_cv_have_openlog_decl" >&6
+if test "$ice_cv_have_openlog_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENLOG_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_pclose=no
+
+for ac_func in pclose
+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_pclose=yes
+fi
+done
+
+if test "${ice_have_pclose}" = yes; then
+echo "$as_me:$LINENO: checking for pclose declaration in stdio.h" >&5
+echo $ECHO_N "checking for pclose declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_pclose_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_pclose_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}pclose[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_pclose_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_pclose_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}pclose[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_pclose_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_pclose_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_pclose_decl" >&5
+echo "${ECHO_T}$ice_cv_have_pclose_decl" >&6
+if test "$ice_cv_have_pclose_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PCLOSE_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_perror=no
+
+for ac_func in perror
+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_perror=yes
+fi
+done
+
+if test "${ice_have_perror}" = yes; then
+echo "$as_me:$LINENO: checking for perror declaration in stdio.h" >&5
+echo $ECHO_N "checking for perror declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_perror_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_perror_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}perror[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_perror_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_perror_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}perror[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_perror_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_perror_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_perror_decl" >&5
+echo "${ECHO_T}$ice_cv_have_perror_decl" >&6
+if test "$ice_cv_have_perror_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PERROR_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_printf=no
+
+for ac_func in printf
+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_printf=yes
+fi
+done
+
+if test "${ice_have_printf}" = yes; then
+echo "$as_me:$LINENO: checking for printf declaration in stdio.h" >&5
+echo $ECHO_N "checking for printf declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_printf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_printf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}printf[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_printf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_printf_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}printf[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_printf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_printf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_printf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_printf_decl" >&6
+if test "$ice_cv_have_printf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PRINTF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in putenv
+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
+
+fi
+done
+
+
+ice_have_puts=no
+
+for ac_func in puts
+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_puts=yes
+fi
+done
+
+if test "${ice_have_puts}" = yes; then
+echo "$as_me:$LINENO: checking for puts declaration in stdio.h" >&5
+echo $ECHO_N "checking for puts declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_puts_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_puts_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}puts[  ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_puts_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_puts_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}puts[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_puts_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_puts_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_puts_decl" >&5
+echo "${ECHO_T}$ice_cv_have_puts_decl" >&6
+if test "$ice_cv_have_puts_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PUTS_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_realloc=no
+
+for ac_func in realloc
+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_realloc=yes
+fi
+done
+
+if test "${ice_have_realloc}" = yes; then
+echo "$as_me:$LINENO: checking for realloc declaration in stdlib.h" >&5
+echo $ECHO_N "checking for realloc declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_realloc_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_realloc_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}realloc[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_realloc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_realloc_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}realloc[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_realloc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_realloc_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_realloc_decl" >&5
+echo "${ECHO_T}$ice_cv_have_realloc_decl" >&6
+if test "$ice_cv_have_realloc_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_REALLOC_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_recvfrom=no
+
+for ac_func in recvfrom
+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_recvfrom=yes
+fi
+done
+
+if test "${ice_have_recvfrom}" = yes; then
+echo "$as_me:$LINENO: checking for recvfrom declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for recvfrom declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_recvfrom_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_recvfrom_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}recvfrom[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_recvfrom_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_recvfrom_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}recvfrom[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_recvfrom_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_recvfrom_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_recvfrom_decl" >&5
+echo "${ECHO_T}$ice_cv_have_recvfrom_decl" >&6
+if test "$ice_cv_have_recvfrom_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_RECVFROM_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_remove=no
+
+for ac_func in remove
+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_remove=yes
+fi
+done
+
+if test "${ice_have_remove}" = yes; then
+echo "$as_me:$LINENO: checking for remove declaration in stdio.h" >&5
+echo $ECHO_N "checking for remove declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_remove_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_remove_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}remove[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_remove_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_remove_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}remove[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_remove_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_remove_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_remove_decl" >&5
+echo "${ECHO_T}$ice_cv_have_remove_decl" >&6
+if test "$ice_cv_have_remove_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_REMOVE_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_rename=no
+
+for ac_func in rename
+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_rename=yes
+fi
+done
+
+if test "${ice_have_rename}" = yes; then
+echo "$as_me:$LINENO: checking for rename declaration in stdio.h" >&5
+echo $ECHO_N "checking for rename declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_rename_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_rename_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}rename[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_rename_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_rename_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}rename[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_rename_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_rename_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_rename_decl" >&5
+echo "${ECHO_T}$ice_cv_have_rename_decl" >&6
+if test "$ice_cv_have_rename_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_RENAME_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_rewind=no
+
+for ac_func in rewind
+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_rewind=yes
+fi
+done
+
+if test "${ice_have_rewind}" = yes; then
+echo "$as_me:$LINENO: checking for rewind declaration in stdio.h" >&5
+echo $ECHO_N "checking for rewind declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_rewind_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_rewind_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}rewind[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_rewind_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_rewind_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}rewind[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_rewind_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_rewind_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_rewind_decl" >&5
+echo "${ECHO_T}$ice_cv_have_rewind_decl" >&6
+if test "$ice_cv_have_rewind_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_REWIND_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in rmdir
+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
+
+fi
+done
+
+
+ice_have_ruserok=no
+
+for ac_func in ruserok
+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_ruserok=yes
+fi
+done
+
+if test "${ice_have_ruserok}" = yes; then
+echo "$as_me:$LINENO: checking for ruserok declaration in netdb.h sys/socket.h libc.h unistd.h" >&5
+echo $ECHO_N "checking for ruserok declaration in netdb.h sys/socket.h libc.h unistd.h... $ECHO_C" >&6
+if test "${ice_cv_have_ruserok_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_ruserok_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in netdb.h sys/socket.h libc.h unistd.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}ruserok[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_ruserok_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_ruserok_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}ruserok[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_ruserok_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_ruserok_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_ruserok_decl" >&5
+echo "${ECHO_T}$ice_cv_have_ruserok_decl" >&6
+if test "$ice_cv_have_ruserok_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_RUSEROK_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_select=no
+
+for ac_func in select
+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_select=yes
+fi
+done
+
+if test "${ice_have_select}" = yes; then
+echo "$as_me:$LINENO: checking for select declaration in sys/types.h sys/socket.h sys/select.h time.h sys/time.h" >&5
+echo $ECHO_N "checking for select declaration in sys/types.h sys/socket.h sys/select.h time.h sys/time.h... $ECHO_C" >&6
+if test "${ice_cv_have_select_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_select_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.h sys/select.h 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}select[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_select_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_select_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}select[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_select_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_select_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_select_decl" >&5
+echo "${ECHO_T}$ice_cv_have_select_decl" >&6
+if test "$ice_cv_have_select_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SELECT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+       echo "$as_me:$LINENO: checking for select() argument type" >&5
+echo $ECHO_N "checking for select() argument type... $ECHO_C" >&6
+if test "${amanda_cv_select_arg_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               rm -f conftest.c
+               cat <<EOF >conftest.$ac_ext
+#include "confdefs.h"
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#  include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int main()
+{
+#ifdef FD_SET_POINTER
+       (void)select(0, (fd_set *) 0, (fd_set *) 0, (fd_set *) 0, 0);
+#else
+       (void)select(0, (int *) 0, (int *) 0, (int *) 0, 0);
+#endif
+       return 0;
+}
+EOF
+
+                                                                                                                               amanda_cv_select_arg_type=no
+               select_compile="${CC-cc} -c $CFLAGS $CPPFLAGS"
+               $select_compile -DFD_SET_POINTER conftest.$ac_ext 1>conftest.fd_set 2>&1
+               if test $? -ne 0; then
+                   amanda_cv_select_arg_type=int
+               fi
+               if test "$amanda_cv_select_arg_type" = no; then
+                   $select_compile conftest.$ac_ext 1>conftest.int 2>&1
+                   if test $? -ne 0; then
+                       amanda_cv_select_arg_type=fd_set
+                   fi
+               fi
+               if test "$amanda_cv_select_arg_type" = no; then
+                   wc_fdset=`wc -l <conftest.fd_set`
+                   wc_int=`wc -l <conftest.int`
+                   if test "$wc_fdset" -le "$wc_int"; then
+                       amanda_cv_select_arg_type=fd_set
+                   else
+                       amanda_cv_select_arg_type=int
+                   fi
+               fi
+               rm -f conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_select_arg_type" >&5
+echo "${ECHO_T}$amanda_cv_select_arg_type" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define SELECT_ARG_TYPE $amanda_cv_select_arg_type
+_ACEOF
+
+
+
+
+ice_have_sendto=no
+
+for ac_func in sendto
+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_sendto=yes
+fi
+done
+
+if test "${ice_have_sendto}" = yes; then
+echo "$as_me:$LINENO: checking for sendto declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for sendto declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_sendto_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_sendto_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}sendto[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_sendto_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_sendto_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}sendto[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_sendto_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_sendto_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_sendto_decl" >&5
+echo "${ECHO_T}$ice_cv_have_sendto_decl" >&6
+if test "$ice_cv_have_sendto_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SENDTO_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_setegid=no
+
+for ac_func in setegid
+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_setegid=yes
+fi
+done
+
+if test "${ice_have_setegid}" = yes; then
+echo "$as_me:$LINENO: checking for setegid declaration in unistd.h" >&5
+echo $ECHO_N "checking for setegid declaration in unistd.h... $ECHO_C" >&6
+if test "${ice_cv_have_setegid_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_setegid_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in unistd.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}setegid[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_setegid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setegid_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}setegid[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_setegid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setegid_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_setegid_decl" >&5
+echo "${ECHO_T}$ice_cv_have_setegid_decl" >&6
+if test "$ice_cv_have_setegid_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SETEGID_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_seteuid=no
+
+for ac_func in seteuid
+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_seteuid=yes
+fi
+done
+
+if test "${ice_have_seteuid}" = yes; then
+echo "$as_me:$LINENO: checking for seteuid declaration in unistd.h" >&5
+echo $ECHO_N "checking for seteuid declaration in unistd.h... $ECHO_C" >&6
+if test "${ice_cv_have_seteuid_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_seteuid_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in unistd.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}seteuid[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_seteuid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_seteuid_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}seteuid[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_seteuid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_seteuid_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_seteuid_decl" >&5
+echo "${ECHO_T}$ice_cv_have_seteuid_decl" >&6
+if test "$ice_cv_have_seteuid_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SETEUID_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in setmntent
+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
+
+fi
+done
+
+
+ice_have_setresgid=no
+
+for ac_func in setresgid
+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_setresgid=yes
+fi
+done
+
+if test "${ice_have_setresgid}" = yes; then
+echo "$as_me:$LINENO: checking for setresgid declaration in unistd.h" >&5
+echo $ECHO_N "checking for setresgid declaration in unistd.h... $ECHO_C" >&6
+if test "${ice_cv_have_setresgid_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_setresgid_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in unistd.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}setresgid[     ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_setresgid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setresgid_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}setresgid[     ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_setresgid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setresgid_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_setresgid_decl" >&5
+echo "${ECHO_T}$ice_cv_have_setresgid_decl" >&6
+if test "$ice_cv_have_setresgid_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SETRESGID_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_setresuid=no
+
+for ac_func in setresuid
+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_setresuid=yes
+fi
+done
+
+if test "${ice_have_setresuid}" = yes; then
+echo "$as_me:$LINENO: checking for setresuid declaration in unistd.h" >&5
+echo $ECHO_N "checking for setresuid declaration in unistd.h... $ECHO_C" >&6
+if test "${ice_cv_have_setresuid_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_setresuid_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in unistd.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}setresuid[     ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_setresuid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setresuid_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}setresuid[     ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_setresuid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setresuid_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_setresuid_decl" >&5
+echo "${ECHO_T}$ice_cv_have_setresuid_decl" >&6
+if test "$ice_cv_have_setresuid_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SETRESUID_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+echo "$as_me:$LINENO: checking for setpgid" >&5
+echo $ECHO_N "checking for setpgid... $ECHO_C" >&6
+if test "${ac_cv_func_setpgid+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 setpgid to an innocuous variant, in case <limits.h> declares setpgid.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define setpgid innocuous_setpgid
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char setpgid (); 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 setpgid
+
+/* 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 setpgid ();
+/* 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_setpgid) || defined (__stub___setpgid)
+choke me
+#else
+char (*f) () = setpgid;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != setpgid;
+  ;
+  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
+  ac_cv_func_setpgid=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_setpgid=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_setpgid" >&5
+echo "${ECHO_T}$ac_cv_func_setpgid" >&6
+if test $ac_cv_func_setpgid = yes; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SETPGID 1
+_ACEOF
+
+
+ice_have_setpgid=no
+
+for ac_func in setpgid
+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_setpgid=yes
+fi
+done
+
+if test "${ice_have_setpgid}" = yes; then
+echo "$as_me:$LINENO: checking for setpgid declaration in sys/types.h unistd.h" >&5
+echo $ECHO_N "checking for setpgid declaration in sys/types.h unistd.h... $ECHO_C" >&6
+if test "${ice_cv_have_setpgid_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_setpgid_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h unistd.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}setpgid[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_setpgid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setpgid_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}setpgid[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_setpgid_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setpgid_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_setpgid_decl" >&5
+echo "${ECHO_T}$ice_cv_have_setpgid_decl" >&6
+if test "$ice_cv_have_setpgid_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SETPGID_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+fi
+
+echo "$as_me:$LINENO: checking for setpgrp" >&5
+echo $ECHO_N "checking for setpgrp... $ECHO_C" >&6
+if test "${ac_cv_func_setpgrp+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 setpgrp to an innocuous variant, in case <limits.h> declares setpgrp.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define setpgrp innocuous_setpgrp
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char setpgrp (); 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 setpgrp
+
+/* 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 setpgrp ();
+/* 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_setpgrp) || defined (__stub___setpgrp)
+choke me
+#else
+char (*f) () = setpgrp;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != setpgrp;
+  ;
+  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
+  ac_cv_func_setpgrp=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_setpgrp=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_setpgrp" >&5
+echo "${ECHO_T}$ac_cv_func_setpgrp" >&6
+if test $ac_cv_func_setpgrp = yes; then
+  echo "$as_me:$LINENO: checking whether setpgrp takes no argument" >&5
+echo $ECHO_N "checking whether setpgrp takes no argument... $ECHO_C" >&6
+if test "${ac_cv_func_setpgrp_void+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot check setpgrp when cross compiling" >&5
+echo "$as_me: error: cannot check setpgrp when cross compiling" >&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.  */
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+int
+main ()
+{
+/* If this system has a BSD-style setpgrp which takes arguments,
+  setpgrp(1, 1) will fail with ESRCH and return -1, in that case
+  exit successfully. */
+  exit (setpgrp (1,1) == -1 ? 0 : 1);
+  ;
+  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_func_setpgrp_void=no
+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 )
+ac_cv_func_setpgrp_void=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_setpgrp_void" >&5
+echo "${ECHO_T}$ac_cv_func_setpgrp_void" >&6
+if test $ac_cv_func_setpgrp_void = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define SETPGRP_VOID 1
+_ACEOF
+
+fi
+
+fi
+
+
+ice_have_setpgrp=no
+
+for ac_func in setpgrp
+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_setpgrp=yes
+fi
+done
+
+if test "${ice_have_setpgrp}" = yes; then
+echo "$as_me:$LINENO: checking for setpgrp declaration in sys/types.h unistd.h libc.h" >&5
+echo $ECHO_N "checking for setpgrp declaration in sys/types.h unistd.h libc.h... $ECHO_C" >&6
+if test "${ice_cv_have_setpgrp_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_setpgrp_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in 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}setpgrp[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_setpgrp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setpgrp_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}setpgrp[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_setpgrp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setpgrp_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_setpgrp_decl" >&5
+echo "${ECHO_T}$ice_cv_have_setpgrp_decl" >&6
+if test "$ice_cv_have_setpgrp_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SETPGRP_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+ice_have_setsockopt=no
+
+for ac_func in setsockopt
+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_setsockopt=yes
+fi
+done
+
+if test "${ice_have_setsockopt}" = yes; then
+echo "$as_me:$LINENO: checking for setsockopt declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for setsockopt declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_setsockopt_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_setsockopt_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}setsockopt[    ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_setsockopt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setsockopt_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}setsockopt[    ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_setsockopt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_setsockopt_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_setsockopt_decl" >&5
+echo "${ECHO_T}$ice_cv_have_setsockopt_decl" >&6
+if test "$ice_cv_have_setsockopt_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SETSOCKOPT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+for ac_func in shmget
+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
+
+
+       echo "$as_me:$LINENO: checking for shmdt() argument type" >&5
+echo $ECHO_N "checking for shmdt() argument type... $ECHO_C" >&6
+if test "${amanda_cv_shmdt_arg_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+               if test "$ac_cv_func_shmget" = yes; then
+                   cat <<EOF >conftest.$ac_ext
+#include "confdefs.h"
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_IPC_H
+# include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+# include <sys/shm.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" void *shmat(int, void *, int);
+#else
+void *shmat();
+#endif
+
+int main()
+{
+    int i;
+    return 0;
+}
+EOF
+                   ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext >/dev/null 2>/dev/null
+                   if test $? = 0; then
+                       amanda_cv_shmdt_arg_type=void
+                   else
+                       amanda_cv_shmdt_arg_type=char
+                   fi
+                   rm -f conftest*
+               else
+                   amanda_cv_shmdt_arg_type=nothing
+               fi
+
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_shmdt_arg_type" >&5
+echo "${ECHO_T}$amanda_cv_shmdt_arg_type" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define SHM_ARG_TYPE $amanda_cv_shmdt_arg_type
+_ACEOF
+
+
+
+       case "$FORCE_MMAP" in
+       n | no)
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYSVSHM 1
+_ACEOF
+
+         ;;
+       esac
+
+
+fi
+done
+
+
+ice_have_shmat=no
+
+for ac_func in shmat
+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_shmat=yes
+fi
+done
+
+if test "${ice_have_shmat}" = yes; then
+echo "$as_me:$LINENO: checking for shmat declaration in sys/types.h sys/ipc.h sys/shm.h" >&5
+echo $ECHO_N "checking for shmat declaration in sys/types.h sys/ipc.h sys/shm.h... $ECHO_C" >&6
+if test "${ice_cv_have_shmat_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_shmat_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/ipc.h sys/shm.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}shmat[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_shmat_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmat_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}shmat[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_shmat_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmat_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_shmat_decl" >&5
+echo "${ECHO_T}$ice_cv_have_shmat_decl" >&6
+if test "$ice_cv_have_shmat_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SHMAT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_shmctl=no
+
+for ac_func in shmctl
+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_shmctl=yes
+fi
+done
+
+if test "${ice_have_shmctl}" = yes; then
+echo "$as_me:$LINENO: checking for shmctl declaration in sys/types.h sys/ipc.h sys/shm.h" >&5
+echo $ECHO_N "checking for shmctl declaration in sys/types.h sys/ipc.h sys/shm.h... $ECHO_C" >&6
+if test "${ice_cv_have_shmctl_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_shmctl_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/ipc.h sys/shm.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}shmctl[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_shmctl_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmctl_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}shmctl[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_shmctl_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmctl_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_shmctl_decl" >&5
+echo "${ECHO_T}$ice_cv_have_shmctl_decl" >&6
+if test "$ice_cv_have_shmctl_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SHMCTL_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_shmdt=no
+
+for ac_func in shmdt
+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_shmdt=yes
+fi
+done
+
+if test "${ice_have_shmdt}" = yes; then
+echo "$as_me:$LINENO: checking for shmdt declaration in sys/types.h sys/ipc.h sys/shm.h" >&5
+echo $ECHO_N "checking for shmdt declaration in sys/types.h sys/ipc.h sys/shm.h... $ECHO_C" >&6
+if test "${ice_cv_have_shmdt_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_shmdt_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/ipc.h sys/shm.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}shmdt[         ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_shmdt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmdt_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}shmdt[         ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_shmdt_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmdt_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_shmdt_decl" >&5
+echo "${ECHO_T}$ice_cv_have_shmdt_decl" >&6
+if test "$ice_cv_have_shmdt_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SHMDT_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_shmget=no
+
+for ac_func in shmget
+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_shmget=yes
+fi
+done
+
+if test "${ice_have_shmget}" = yes; then
+echo "$as_me:$LINENO: checking for shmget declaration in sys/types.h sys/ipc.h sys/shm.h" >&5
+echo $ECHO_N "checking for shmget declaration in sys/types.h sys/ipc.h sys/shm.h... $ECHO_C" >&6
+if test "${ice_cv_have_shmget_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_shmget_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/ipc.h sys/shm.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}shmget[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_shmget_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmget_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}shmget[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_shmget_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shmget_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_shmget_decl" >&5
+echo "${ECHO_T}$ice_cv_have_shmget_decl" >&6
+if test "$ice_cv_have_shmget_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SHMGET_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+if test "$ac_cv_func_mmap_fixed_mapped" != yes; then
+    case "$FORCE_MMAP" in
+    n | no)
+       if test "$ac_cv_func_shmget" != yes; then
+           { echo "$as_me:$LINENO: WARNING: *** Neither shmget() nor mmap() found!" >&5
+echo "$as_me: WARNING: *** Neither shmget() nor mmap() found!" >&2;}
+           { echo "$as_me:$LINENO: WARNING: *** This system will not support the Amanda server." >&5
+echo "$as_me: WARNING: *** This system will not support the Amanda server." >&2;}
+           NO_SERVER_MODE=true
+       fi
+      ;;
+    y | ye | yes)
+       { echo "$as_me:$LINENO: WARNING: *** --with-mmap used on a system with no mmap() support!" >&5
+echo "$as_me: WARNING: *** --with-mmap used on a system with no mmap() support!" >&2;}
+       { echo "$as_me:$LINENO: WARNING: *** This system will not support the Amanda server." >&5
+echo "$as_me: WARNING: *** This system will not support the Amanda server." >&2;}
+       NO_SERVER_MODE=true
+      ;;
+    esac
+fi
+
+
+ice_have_shquote=no
+
+for ac_func in shquote
+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_shquote=yes
+fi
+done
+
+if test "${ice_have_shquote}" = yes; then
+echo "$as_me:$LINENO: checking for shquote declaration in stdlib.h" >&5
+echo $ECHO_N "checking for shquote declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_shquote_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_shquote_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}shquote[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_shquote_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shquote_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}shquote[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_shquote_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_shquote_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_shquote_decl" >&5
+echo "${ECHO_T}$ice_cv_have_shquote_decl" >&6
+if test "$ice_cv_have_shquote_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SHQUOTE_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+ice_have_snprintf=no
+
+for ac_func in snprintf
+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_snprintf=yes
+fi
+done
+
+if test "${ice_have_snprintf}" = yes; then
+echo "$as_me:$LINENO: checking for snprintf declaration in stdio.h" >&5
+echo $ECHO_N "checking for snprintf declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_snprintf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_snprintf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}snprintf[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_snprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_snprintf_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}snprintf[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_snprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_snprintf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_snprintf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_snprintf_decl" >&6
+if test "$ice_cv_have_snprintf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SNPRINTF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_vsnprintf=no
+
+for ac_func in vsnprintf
+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_vsnprintf=yes
+fi
+done
+
+if test "${ice_have_vsnprintf}" = yes; then
+echo "$as_me:$LINENO: checking for vsnprintf declaration in stdio.h" >&5
+echo $ECHO_N "checking for vsnprintf declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_vsnprintf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_vsnprintf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}vsnprintf[     ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_vsnprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vsnprintf_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}vsnprintf[     ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_vsnprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vsnprintf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_vsnprintf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_vsnprintf_decl" >&6
+if test "$ice_cv_have_vsnprintf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_VSNPRINTF_DECL 1
+_ACEOF
+
+fi
+fi
+
+if test x"$ice_have_snprintf" != x"yes" ||
+   test x"$ice_have_vsnprintf" != x"yes"; then
+    case $LIBOBJS in
+    "snprintf.$ac_objext"   | \
+  *" snprintf.$ac_objext"   | \
+    "snprintf.$ac_objext "* | \
+  *" snprintf.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" ;;
+esac
+
+    if false; then :
+
+for ac_func in snprintf
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+    fi
+fi
+
+
+
+
+for ac_func in sigaction sigemptyset sigvec
+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
+
+fi
+done
+
+
+ice_have_socket=no
+
+for ac_func in socket
+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_socket=yes
+fi
+done
+
+if test "${ice_have_socket}" = yes; then
+echo "$as_me:$LINENO: checking for socket declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for socket declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_socket_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_socket_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}socket[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_socket_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_socket_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}socket[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_socket_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_socket_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_socket_decl" >&5
+echo "${ECHO_T}$ice_cv_have_socket_decl" >&6
+if test "$ice_cv_have_socket_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SOCKET_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_socketpair=no
+
+for ac_func in socketpair
+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_socketpair=yes
+fi
+done
+
+if test "${ice_have_socketpair}" = yes; then
+echo "$as_me:$LINENO: checking for socketpair declaration in sys/types.h sys/socket.h" >&5
+echo $ECHO_N "checking for socketpair declaration in sys/types.h sys/socket.h... $ECHO_C" >&6
+if test "${ice_cv_have_socketpair_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_socketpair_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in sys/types.h sys/socket.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}socketpair[    ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_socketpair_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_socketpair_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}socketpair[    ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_socketpair_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_socketpair_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_socketpair_decl" >&5
+echo "${ECHO_T}$ice_cv_have_socketpair_decl" >&6
+if test "$ice_cv_have_socketpair_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SOCKETPAIR_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_sscanf=no
+
+for ac_func in sscanf
+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_sscanf=yes
+fi
+done
+
+if test "${ice_have_sscanf}" = yes; then
+echo "$as_me:$LINENO: checking for sscanf declaration in stdio.h" >&5
+echo $ECHO_N "checking for sscanf declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_sscanf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_sscanf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}sscanf[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_sscanf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_sscanf_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}sscanf[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_sscanf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_sscanf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_sscanf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_sscanf_decl" >&6
+if test "$ice_cv_have_sscanf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SSCANF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+for ac_func in statfs statvfs
+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
+
+fi
+done
+
+
+for ac_func in strerror
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+ice_have_strerror=no
+
+for ac_func in strerror
+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_strerror=yes
+fi
+done
+
+if test "${ice_have_strerror}" = yes; then
+echo "$as_me:$LINENO: checking for strerror declaration in string.h strings.h" >&5
+echo $ECHO_N "checking for strerror declaration in string.h strings.h... $ECHO_C" >&6
+if test "${ice_cv_have_strerror_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_strerror_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in string.h strings.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}strerror[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_strerror_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strerror_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}strerror[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_strerror_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strerror_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_strerror_decl" >&5
+echo "${ECHO_T}$ice_cv_have_strerror_decl" >&6
+if test "$ice_cv_have_strerror_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRERROR_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in strftime
+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
+
+else
+  # strftime is in -lintl on SCO UNIX.
+echo "$as_me:$LINENO: checking for strftime in -lintl" >&5
+echo $ECHO_N "checking for strftime in -lintl... $ECHO_C" >&6
+if test "${ac_cv_lib_intl_strftime+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.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 strftime ();
+int
+main ()
+{
+strftime ();
+  ;
+  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
+  ac_cv_lib_intl_strftime=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_intl_strftime=no
+fi
+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_intl_strftime" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_strftime" >&6
+if test $ac_cv_lib_intl_strftime = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRFTIME 1
+_ACEOF
+
+LIBS="-lintl $LIBS"
+fi
+
+fi
+done
+
+
+for ac_func in strftime
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+ice_have_strftime=no
+
+for ac_func in strftime
+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_strftime=yes
+fi
+done
+
+if test "${ice_have_strftime}" = yes; then
+echo "$as_me:$LINENO: checking for strftime declaration in time.h sys/time.h" >&5
+echo $ECHO_N "checking for strftime declaration in time.h sys/time.h... $ECHO_C" >&6
+if test "${ice_cv_have_strftime_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_strftime_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}strftime[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_strftime_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strftime_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}strftime[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_strftime_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strftime_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_strftime_decl" >&5
+echo "${ECHO_T}$ice_cv_have_strftime_decl" >&6
+if test "$ice_cv_have_strftime_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRFTIME_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in strncasecmp
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+ice_have_strncasecmp=no
+
+for ac_func in strncasecmp
+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_strncasecmp=yes
+fi
+done
+
+if test "${ice_have_strncasecmp}" = yes; then
+echo "$as_me:$LINENO: checking for strncasecmp declaration in string.h strings.h" >&5
+echo $ECHO_N "checking for strncasecmp declaration in string.h strings.h... $ECHO_C" >&6
+if test "${ice_cv_have_strncasecmp_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_strncasecmp_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in string.h strings.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}strncasecmp[   ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_strncasecmp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strncasecmp_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}strncasecmp[   ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_strncasecmp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strncasecmp_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_strncasecmp_decl" >&5
+echo "${ECHO_T}$ice_cv_have_strncasecmp_decl" >&6
+if test "$ice_cv_have_strncasecmp_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRNCASECMP_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in strstr
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+ice_have_syslog=no
+
+for ac_func in syslog
+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_syslog=yes
+fi
+done
+
+if test "${ice_have_syslog}" = yes; then
+echo "$as_me:$LINENO: checking for syslog declaration in syslog.h" >&5
+echo $ECHO_N "checking for syslog declaration in syslog.h... $ECHO_C" >&6
+if test "${ice_cv_have_syslog_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_syslog_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in syslog.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}syslog[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_syslog_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_syslog_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}syslog[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_syslog_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_syslog_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_syslog_decl" >&5
+echo "${ECHO_T}$ice_cv_have_syslog_decl" >&6
+if test "$ice_cv_have_syslog_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SYSLOG_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_system=no
+
+for ac_func in system
+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_system=yes
+fi
+done
+
+if test "${ice_have_system}" = yes; then
+echo "$as_me:$LINENO: checking for system declaration in stdlib.h" >&5
+echo $ECHO_N "checking for system declaration in stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_system_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_system_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}system[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_system_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_system_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}system[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_system_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_system_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_system_decl" >&5
+echo "${ECHO_T}$ice_cv_have_system_decl" >&6
+if test "$ice_cv_have_system_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SYSTEM_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_time=no
+
+for ac_func in time
+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_time=yes
+fi
+done
+
+if test "${ice_have_time}" = yes; then
+echo "$as_me:$LINENO: checking for time declaration in time.h sys/time.h" >&5
+echo $ECHO_N "checking for time declaration in time.h sys/time.h... $ECHO_C" >&6
+if test "${ice_cv_have_time_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_time_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}time[  ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_time_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_time_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}time[  ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_time_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_time_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_time_decl" >&5
+echo "${ECHO_T}$ice_cv_have_time_decl" >&6
+if test "$ice_cv_have_time_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TIME_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_tolower=no
+
+for ac_func in tolower
+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_tolower=yes
+fi
+done
+
+if test "${ice_have_tolower}" = yes; then
+echo "$as_me:$LINENO: checking for tolower declaration in ctype.h" >&5
+echo $ECHO_N "checking for tolower declaration in ctype.h... $ECHO_C" >&6
+if test "${ice_cv_have_tolower_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_tolower_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in ctype.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}tolower[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_tolower_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_tolower_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}tolower[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_tolower_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_tolower_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_tolower_decl" >&5
+echo "${ECHO_T}$ice_cv_have_tolower_decl" >&6
+if test "$ice_cv_have_tolower_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TOLOWER_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_toupper=no
+
+for ac_func in toupper
+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_toupper=yes
+fi
+done
+
+if test "${ice_have_toupper}" = yes; then
+echo "$as_me:$LINENO: checking for toupper declaration in ctype.h" >&5
+echo $ECHO_N "checking for toupper declaration in ctype.h... $ECHO_C" >&6
+if test "${ice_cv_have_toupper_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_toupper_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in ctype.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}toupper[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_toupper_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_toupper_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}toupper[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_toupper_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_toupper_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_toupper_decl" >&5
+echo "${ECHO_T}$ice_cv_have_toupper_decl" >&6
+if test "$ice_cv_have_toupper_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_TOUPPER_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_ungetc=no
+
+for ac_func in ungetc
+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_ungetc=yes
+fi
+done
+
+if test "${ice_have_ungetc}" = yes; then
+echo "$as_me:$LINENO: checking for ungetc declaration in stdio.h" >&5
+echo $ECHO_N "checking for ungetc declaration in stdio.h... $ECHO_C" >&6
+if test "${ice_cv_have_ungetc_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_ungetc_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.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}ungetc[        ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_ungetc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_ungetc_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}ungetc[        ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_ungetc_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_ungetc_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_ungetc_decl" >&5
+echo "${ECHO_T}$ice_cv_have_ungetc_decl" >&6
+if test "$ice_cv_have_ungetc_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UNGETC_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+for ac_func in vprintf
+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
+
+echo "$as_me:$LINENO: checking for _doprnt" >&5
+echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6
+if test "${ac_cv_func__doprnt+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 _doprnt to an innocuous variant, in case <limits.h> declares _doprnt.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char _doprnt (); 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 _doprnt
+
+/* 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 _doprnt ();
+/* 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__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+char (*f) () = _doprnt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != _doprnt;
+  ;
+  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
+  ac_cv_func__doprnt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func__doprnt=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5
+echo "${ECHO_T}$ac_cv_func__doprnt" >&6
+if test $ac_cv_func__doprnt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DOPRNT 1
+_ACEOF
+
+fi
+
+fi
+done
+
+
+
+ice_have_vfprintf=no
+
+for ac_func in vfprintf
+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_vfprintf=yes
+fi
+done
+
+if test "${ice_have_vfprintf}" = yes; then
+echo "$as_me:$LINENO: checking for vfprintf declaration in stdio.h stdlib.h" >&5
+echo $ECHO_N "checking for vfprintf declaration in stdio.h stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_vfprintf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_vfprintf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.h 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}vfprintf[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_vfprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vfprintf_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}vfprintf[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_vfprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vfprintf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_vfprintf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_vfprintf_decl" >&6
+if test "$ice_cv_have_vfprintf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_VFPRINTF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_vprintf=no
+
+for ac_func in vprintf
+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_vprintf=yes
+fi
+done
+
+if test "${ice_have_vprintf}" = yes; then
+echo "$as_me:$LINENO: checking for vprintf declaration in stdio.h stdlib.h" >&5
+echo $ECHO_N "checking for vprintf declaration in stdio.h stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_vprintf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_vprintf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.h 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}vprintf[       ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_vprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vprintf_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}vprintf[       ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_vprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vprintf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_vprintf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_vprintf_decl" >&6
+if test "$ice_cv_have_vprintf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+ice_have_vsprintf=no
+
+for ac_func in vsprintf
+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_vsprintf=yes
+fi
+done
+
+if test "${ice_have_vsprintf}" = yes; then
+echo "$as_me:$LINENO: checking for vsprintf declaration in stdio.h stdlib.h" >&5
+echo $ECHO_N "checking for vsprintf declaration in stdio.h stdlib.h... $ECHO_C" >&6
+if test "${ice_cv_have_vsprintf_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_vsprintf_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in stdio.h 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}vsprintf[      ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_vsprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vsprintf_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}vsprintf[      ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_vsprintf_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_vsprintf_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_vsprintf_decl" >&5
+echo "${ECHO_T}$ice_cv_have_vsprintf_decl" >&6
+if test "$ice_cv_have_vsprintf_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_VSPRINTF_DECL 1
+_ACEOF
+
+fi
+fi
+
+echo "$as_me:$LINENO: checking for wait4" >&5
+echo $ECHO_N "checking for wait4... $ECHO_C" >&6
+if test "${ac_cv_func_wait4+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 wait4 to an innocuous variant, in case <limits.h> declares wait4.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define wait4 innocuous_wait4
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char wait4 (); 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 wait4
+
+/* 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 wait4 ();
+/* 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_wait4) || defined (__stub___wait4)
+choke me
+#else
+char (*f) () = wait4;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != wait4;
+  ;
+  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
+  ac_cv_func_wait4=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_wait4=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_wait4" >&5
+echo "${ECHO_T}$ac_cv_func_wait4" >&6
+
+
+for ac_func in waitpid
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+for ac_func in strcasecmp
+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
+
+else
+  case $LIBOBJS in
+    "$ac_func.$ac_objext"   | \
+  *" $ac_func.$ac_objext"   | \
+    "$ac_func.$ac_objext "* | \
+  *" $ac_func.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+esac
+
+fi
+done
+
+
+
+ice_have_strcasecmp=no
+
+for ac_func in strcasecmp
+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_strcasecmp=yes
+fi
+done
+
+if test "${ice_have_strcasecmp}" = yes; then
+echo "$as_me:$LINENO: checking for strcasecmp declaration in string.h strings.h" >&5
+echo $ECHO_N "checking for strcasecmp declaration in string.h strings.h... $ECHO_C" >&6
+if test "${ice_cv_have_strcasecmp_decl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ice_cv_have_strcasecmp_decl=no
+ice_re_params='[a-zA-Z_][a-zA-Z0-9_]*'
+ice_re_word='(^|[^a-zA-Z0-9_])'
+for header in string.h strings.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}strcasecmp[    ]*\(" >/dev/null 2>&1; then
+  ice_cv_have_strcasecmp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strcasecmp_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}strcasecmp[    ]*$ice_re_params\(\(" >/dev/null 2>&1; then
+  ice_cv_have_strcasecmp_decl=yes
+fi
+rm -f conftest*
+
+if test "$ice_cv_have_strcasecmp_decl" = yes; then
+       break
+fi
+done
+
+fi
+
+echo "$as_me:$LINENO: result: $ice_cv_have_strcasecmp_decl" >&5
+echo "${ECHO_T}$ice_cv_have_strcasecmp_decl" >&6
+if test "$ice_cv_have_strcasecmp_decl" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRCASECMP_DECL 1
+_ACEOF
+
+fi
+fi
+
+
+
+for ac_func in fnmatch
+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
+
+fi
+done
+
+
+if test "$ac_cv_func_fnmatch" != yes -a "$USE_QUICK_AND_DIRTY_ESTIMATES" != yes ; then
+    { echo "$as_me:$LINENO: WARNING: --with-qde and no fnmatch -- gnutar exclude files will not work" >&5
+echo "$as_me: WARNING: --with-qde and no fnmatch -- gnutar exclude files will not work" >&2;}
+fi
+
+echo "$as_me:$LINENO: checking disk device prefixes" >&5
+echo $ECHO_N "checking disk device prefixes... $ECHO_C" >&6
+dfline=`(
+    df / | while read line; do
+       set -- $line
+       while test $# -gt 0; do
+           if test "$1" = "/"; then
+               echo $line
+               break 2
+           fi
+           shift
+       done
+    done
+) | sed 's/(//' | sed 's/)//' `
+
+mount=`(
+    set -- $dfline
+    while test $# -gt 0; do
+       if expr "$1" : '.*dev' >/dev/null 2>&1; then
+           echo $1
+           break
+       fi
+       shift
+    done
+)`
+
+if test "$DEV_PREFIX" && test "$RDEV_PREFIX"; then
+    echo "$as_me:$LINENO: result: (predefined) $DEV_PREFIX - $RDEV_PREFIX" >&5
+echo "${ECHO_T}(predefined) $DEV_PREFIX - $RDEV_PREFIX" >&6
+else
+    if test -d /dev/dsk; then
+       DEV_PREFIX=/dev/dsk/
+       if test -d /dev/rdsk; then
+           RDEV_PREFIX=/dev/rdsk/
+       else
+           RDEV_PREFIX=/dev/dsk/
+       fi
+    elif test -d /dev; then
+       case "$target" in
+           *-sni-sysv4)
+               dev_prefix=/dev/dsk/
+               rdev_prefix=/dev/rdsk/
+               { echo "$as_me:$LINENO: WARNING: \"*** Run amsinixfixdevs on Sinix systems using VxFS.\"" >&5
+echo "$as_me: WARNING: \"*** Run amsinixfixdevs on Sinix systems using VxFS.\"" >&2;}
+               ;;
+
+            *)
+               DEV_PREFIX=/dev/
+               # Some systems, notably Linux, do not have raw disk devices
+               # names.  Check this by trying to see if a raw disk device name
+               # exists using the normal raw device path prepended to the
+               # mount point of the root filesystem.
+               if test "$mount"; then
+                   dev_name="/dev/r`basename $mount`"
+                   if test -b $dev_name -o -c $dev_name; then
+                       RDEV_PREFIX=/dev/r
+                   else
+                       RDEV_PREFIX=/dev/
+                   fi
+               else
+                   RDEV_PREFIX=/dev/r
+               fi
+               ;;
+       esac
+    else
+       DEV_PREFIX=/
+       RDEV_PREFIX=/
+    fi
+    echo "$as_me:$LINENO: result: $DEV_PREFIX - $RDEV_PREFIX" >&5
+echo "${ECHO_T}$DEV_PREFIX - $RDEV_PREFIX" >&6
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define DEV_PREFIX "${DEV_PREFIX}"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define RDEV_PREFIX "${RDEV_PREFIX}"
+_ACEOF
+
+
+case $mount in
+    /dev/vg*)
+       { echo "$as_me:$LINENO: WARNING: \"*** Run amhpfixdevs on HP-UX systems using /dev/vg??.\"" >&5
+echo "$as_me: WARNING: \"*** Run amhpfixdevs on HP-UX systems using /dev/vg??.\"" >&2;}
+       ;;
+esac
+
+echo "$as_me:$LINENO: checking whether posix fcntl locking works" >&5
+echo $ECHO_N "checking whether posix fcntl locking works... $ECHO_C" >&6
+if test "${amanda_cv_posix_filelocking+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+       if test "$cross_compiling" = yes; then
+
+       amanda_cv_posix_filelocking="no (cannot run test)"
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_POSIX_FCNTL
+#include "${srcdir-.}/common-src/amflock.c"
+
+_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
+
+       amanda_cv_posix_filelocking=yes
+
+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 )
+
+       amanda_cv_posix_filelocking="no"
+
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+    rm -f /tmp/conftest.lock
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_posix_filelocking" >&5
+echo "${ECHO_T}$amanda_cv_posix_filelocking" >&6
+if test "$amanda_cv_posix_filelocking" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_POSIX_FCNTL 1
+_ACEOF
+
+    HAS_WORKING_FILE_LOCK=1
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    echo "$as_me:$LINENO: checking whether flock locking works" >&5
+echo $ECHO_N "checking whether flock locking works... $ECHO_C" >&6
+if test "${amanda_cv_flock_filelocking+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           if test "$cross_compiling" = yes; then
+
+                   amanda_cv_flock_filelocking="no (cannot run test)"
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_FLOCK
+#include "${srcdir-.}/common-src/amflock.c"
+
+_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
+
+                   amanda_cv_flock_filelocking="yes"
+
+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 )
+
+                   amanda_cv_flock_filelocking="no"
+
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+       rm -f /tmp/conftest.lock
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_flock_filelocking" >&5
+echo "${ECHO_T}$amanda_cv_flock_filelocking" >&6
+    if test "$amanda_cv_flock_filelocking" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_FLOCK 1
+_ACEOF
+
+       HAS_WORKING_FILE_LOCK=1
+    fi
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    echo "$as_me:$LINENO: checking whether lockf locking works" >&5
+echo $ECHO_N "checking whether lockf locking works... $ECHO_C" >&6
+if test "${amanda_cv_lockf_filelocking+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           if test "$cross_compiling" = yes; then
+
+                   amanda_cv_lockf_filelocking="no (cannot run test)"
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_LOCKF
+#include "${srcdir-.}/common-src/amflock.c"
+
+_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
+
+                   amanda_cv_lockf_filelocking="yes"
+
+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 )
+
+                   amanda_cv_lockf_filelocking="no"
+
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+       rm -f /tmp/conftest.lock
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_lockf_filelocking" >&5
+echo "${ECHO_T}$amanda_cv_lockf_filelocking" >&6
+    if test "$amanda_cv_lockf_filelocking" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_LOCKF 1
+_ACEOF
+
+       HAS_WORKING_FILE_LOCK=1
+    fi
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    echo "$as_me:$LINENO: checking whether lnlock locking works" >&5
+echo $ECHO_N "checking whether lnlock locking works... $ECHO_C" >&6
+if test "${amanda_cv_lnlock_filelocking+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+           if test "$cross_compiling" = yes; then
+
+                   amanda_cv_lnlock_filelocking="no (cannot run test)"
+
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_LNLOCK
+#include "${srcdir-.}/common-src/amflock.c"
+#include "${srcdir-.}/common-src/alloc.c"
+#include "${srcdir-.}/common-src/error.c"
+#include "${srcdir-.}/common-src/snprintf.c"
+
+_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
+
+                   amanda_cv_lnlock_filelocking="yes"
+
+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 )
+
+                   amanda_cv_lnlock_filelocking="no"
+
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+       rm -f /tmp/conftest.lock
+
+fi
+echo "$as_me:$LINENO: result: $amanda_cv_lnlock_filelocking" >&5
+echo "${ECHO_T}$amanda_cv_lnlock_filelocking" >&6
+    if test "$amanda_cv_lnlock_filelocking" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_LNLOCK 1
+_ACEOF
+
+       HAS_WORKING_FILE_LOCK=1
+    fi
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    { echo "$as_me:$LINENO: WARNING: *** No working file locking capability found!" >&5
+echo "$as_me: WARNING: *** No working file locking capability found!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: *** Be VERY VERY careful." >&5
+echo "$as_me: WARNING: *** Be VERY VERY careful." >&2;}
+fi
+
+
+
+
+
+
+
+
+
+if test x"$NO_CLIENT_MODE" != x"true"; then
+  WANT_CLIENT_TRUE=
+  WANT_CLIENT_FALSE='#'
+else
+  WANT_CLIENT_TRUE='#'
+  WANT_CLIENT_FALSE=
+fi
+
+
+
+if test ! -z "$SAMBA_CLIENT"; then
+  WANT_SAMBA_TRUE=
+  WANT_SAMBA_FALSE='#'
+else
+  WANT_SAMBA_TRUE='#'
+  WANT_SAMBA_FALSE=
+fi
+
+
+
+if test x"$NO_RESTORE_MODE" != x"true"; then
+  WANT_RESTORE_TRUE=
+  WANT_RESTORE_FALSE='#'
+else
+  WANT_RESTORE_TRUE='#'
+  WANT_RESTORE_FALSE=
+fi
+
+
+
+if test x"$NO_SERVER_MODE" != x"true"; then
+  WANT_SERVER_TRUE=
+  WANT_SERVER_FALSE='#'
+else
+  WANT_SERVER_TRUE='#'
+  WANT_SERVER_FALSE=
+fi
+
+
+
+if test x"$NO_RECOVER_MODE" != x"true" && test x"$NO_CLIENT_MODE" != x"true"; then
+  WANT_RECOVER_TRUE=
+  WANT_RECOVER_FALSE='#'
+else
+  WANT_RECOVER_TRUE='#'
+  WANT_RECOVER_FALSE=
+fi
+
+
+
+if test x"$NO_SERVER_MODE" != x"true" || test x"$NO_RESTORE_MODE" != x"true"; then
+  WANT_TAPE_TRUE=
+  WANT_TAPE_FALSE='#'
+else
+  WANT_TAPE_TRUE='#'
+  WANT_TAPE_FALSE=
+fi
+
+
+
+if test x"$NO_AMPLOT_MODE" != x"true"; then
+  WANT_AMPLOT_TRUE=
+  WANT_AMPLOT_FALSE='#'
+else
+  WANT_AMPLOT_TRUE='#'
+  WANT_AMPLOT_FALSE=
+fi
+
+
+
+if test x"$NO_SCSI_CHANGER_MODE" != x"true"; then
+  WANT_CHG_SCSI_TRUE=
+  WANT_CHG_SCSI_FALSE='#'
+else
+  WANT_CHG_SCSI_TRUE='#'
+  WANT_CHG_SCSI_FALSE=
+fi
+
+
+
+if test x"$NO_CHIO_CHANGER_MODE" != x"true"; then
+  WANT_CHIO_SCSI_TRUE=
+  WANT_CHIO_SCSI_FALSE='#'
+else
+  WANT_CHIO_SCSI_TRUE='#'
+  WANT_CHIO_SCSI_FALSE=
+fi
+
+
+
+if test x"$NEED_RUNTIME_PSEUDO_RELOC" = x"true"; then
+  WANT_RUNTIME_PSEUDO_RELOC_TRUE=
+  WANT_RUNTIME_PSEUDO_RELOC_FALSE='#'
+else
+  WANT_RUNTIME_PSEUDO_RELOC_TRUE='#'
+  WANT_RUNTIME_PSEUDO_RELOC_FALSE=
+fi
+
+
+
+if test x"$NEED_SETUID_CLIENT" != x"false"; then
+  WANT_SETUID_CLIENT_TRUE=
+  WANT_SETUID_CLIENT_FALSE='#'
+else
+  WANT_SETUID_CLIENT_TRUE='#'
+  WANT_SETUID_CLIENT_FALSE=
+fi
+
+
+case "${FORCE_USE_RUNDUMP-${USE_RUNDUMP}}" in
+y |  ye | yes)
+cat >>confdefs.h <<\_ACEOF
+#define USE_RUNDUMP 1
+_ACEOF
+;;
+esac
+
+# This is necessary so that .o files in LIBOBJS are also built via
+# the ANSI2KNR-filtering rules.
+LIBOBJS=`echo "$LIBOBJS" |
+             sed 's,\.[^.]* ,$U&,g;s,\.[^.]*$,$U&,'`
+LTLIBOBJS=`echo "$LIBOBJS" |
+           sed 's,\.[^.]* ,.lo ,g;s,\.[^.]*$,.lo,'`
+
+
+LTALLOCA=`echo "$ALLOCA" | sed 's/\.'"${ac_objext}"'/\.lo/g'`
+
+
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                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 common-src/versuff.c common-src/Makefile example/amanda.conf example/Makefile example/amanda.conf.chg-scsi example/chg-scsi-linux.conf example/chg-scsi-solaris.conf example/chg-scsi-hpux.conf example/chg-mcutil.conf man/amadmin.8 man/amanda.8 man/amcheck.8 man/amcheckdb.8 man/amcleanup.8 man/amdump.8 man/amflush.8 man/amlabel.8 man/amoverview.8 man/amrecover.8 man/amrmtape.8 man/amtoc.8 man/amverify.8 man/Makefile man/amstatus.8 man/amreport.8 man/amgetconf.8 man/amverifyrun.8 man/amtapetype.8 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 tape-src/Makefile config/Makefile Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+       "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+       "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[         ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[    ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[      ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+        sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_CLIENT_TRUE}" && test -z "${WANT_CLIENT_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_CLIENT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_CLIENT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_SAMBA_TRUE}" && test -z "${WANT_SAMBA_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_SAMBA\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_SAMBA\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_RESTORE_TRUE}" && test -z "${WANT_RESTORE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_RESTORE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_RESTORE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_SERVER_TRUE}" && test -z "${WANT_SERVER_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_SERVER\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_SERVER\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_RECOVER_TRUE}" && test -z "${WANT_RECOVER_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_RECOVER\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_RECOVER\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_TAPE_TRUE}" && test -z "${WANT_TAPE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_TAPE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_TAPE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_AMPLOT_TRUE}" && test -z "${WANT_AMPLOT_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_AMPLOT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_AMPLOT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_CHG_SCSI_TRUE}" && test -z "${WANT_CHG_SCSI_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_CHG_SCSI\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_CHG_SCSI\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_CHIO_SCSI_TRUE}" && test -z "${WANT_CHIO_SCSI_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_CHIO_SCSI\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_CHIO_SCSI\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_RUNTIME_PSEUDO_RELOC_TRUE}" && test -z "${WANT_RUNTIME_PSEUDO_RELOC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_RUNTIME_PSEUDO_RELOC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_RUNTIME_PSEUDO_RELOC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${WANT_SETUID_CLIENT_TRUE}" && test -z "${WANT_SETUID_CLIENT_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"WANT_SETUID_CLIENT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"WANT_SETUID_CLIENT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                  instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                  instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+# variables for create stdint.h replacement
+PACKAGE="$PACKAGE"
+VERSION="$VERSION"
+ac_stdint_h="$ac_stdint_h"
+_ac_stdint_h=`echo "_$PACKAGE-$ac_stdint_h" | $as_tr_cpp`
+ac_cv_stdint_message="$ac_cv_stdint_message"
+ac_cv_header_stdint_t="$ac_cv_header_stdint_t"
+ac_cv_header_stdint_x="$ac_cv_header_stdint_x"
+ac_cv_header_stdint_o="$ac_cv_header_stdint_o"
+ac_cv_header_stdint_u="$ac_cv_header_stdint_u"
+ac_cv_type_uint64_t="$ac_cv_type_uint64_t"
+ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t"
+ac_cv_stdint_char_model="$ac_cv_stdint_char_model"
+ac_cv_stdint_long_model="$ac_cv_stdint_long_model"
+ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t"
+ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t"
+ac_cv_type_intmax_t="$ac_cv_type_intmax_t"
+
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "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" ;;
+  "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" ;;
+  "changer-src/chg-chs.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-chs.sh" ;;
+  "changer-src/chg-rth.pl" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-rth.pl" ;;
+  "changer-src/chg-chio.pl" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-chio.pl" ;;
+  "changer-src/chg-zd-mtx.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-zd-mtx.sh" ;;
+  "changer-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES changer-src/Makefile" ;;
+  "changer-src/chg-juke.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-juke.sh" ;;
+  "changer-src/chg-rait.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-rait.sh" ;;
+  "changer-src/chg-null.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-null.sh" ;;
+  "changer-src/chg-mcutil.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-mcutil.sh" ;;
+  "changer-src/chg-disk.sh" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-disk.sh" ;;
+  "changer-src/chg-iomega.pl" ) CONFIG_FILES="$CONFIG_FILES changer-src/chg-iomega.pl" ;;
+  "client-src/patch-system.sh" ) CONFIG_FILES="$CONFIG_FILES client-src/patch-system.sh" ;;
+  "client-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES client-src/Makefile" ;;
+  "common-src/versuff.c" ) CONFIG_FILES="$CONFIG_FILES common-src/versuff.c" ;;
+  "common-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES common-src/Makefile" ;;
+  "example/amanda.conf" ) CONFIG_FILES="$CONFIG_FILES example/amanda.conf" ;;
+  "example/Makefile" ) CONFIG_FILES="$CONFIG_FILES example/Makefile" ;;
+  "example/amanda.conf.chg-scsi" ) CONFIG_FILES="$CONFIG_FILES example/amanda.conf.chg-scsi" ;;
+  "example/chg-scsi-linux.conf" ) CONFIG_FILES="$CONFIG_FILES example/chg-scsi-linux.conf" ;;
+  "example/chg-scsi-solaris.conf" ) CONFIG_FILES="$CONFIG_FILES example/chg-scsi-solaris.conf" ;;
+  "example/chg-scsi-hpux.conf" ) CONFIG_FILES="$CONFIG_FILES example/chg-scsi-hpux.conf" ;;
+  "example/chg-mcutil.conf" ) CONFIG_FILES="$CONFIG_FILES example/chg-mcutil.conf" ;;
+  "man/amadmin.8" ) CONFIG_FILES="$CONFIG_FILES man/amadmin.8" ;;
+  "man/amanda.8" ) CONFIG_FILES="$CONFIG_FILES man/amanda.8" ;;
+  "man/amcheck.8" ) CONFIG_FILES="$CONFIG_FILES man/amcheck.8" ;;
+  "man/amcheckdb.8" ) CONFIG_FILES="$CONFIG_FILES man/amcheckdb.8" ;;
+  "man/amcleanup.8" ) CONFIG_FILES="$CONFIG_FILES man/amcleanup.8" ;;
+  "man/amdump.8" ) CONFIG_FILES="$CONFIG_FILES man/amdump.8" ;;
+  "man/amflush.8" ) CONFIG_FILES="$CONFIG_FILES man/amflush.8" ;;
+  "man/amlabel.8" ) CONFIG_FILES="$CONFIG_FILES man/amlabel.8" ;;
+  "man/amoverview.8" ) CONFIG_FILES="$CONFIG_FILES man/amoverview.8" ;;
+  "man/amrecover.8" ) CONFIG_FILES="$CONFIG_FILES man/amrecover.8" ;;
+  "man/amrmtape.8" ) CONFIG_FILES="$CONFIG_FILES man/amrmtape.8" ;;
+  "man/amtoc.8" ) CONFIG_FILES="$CONFIG_FILES man/amtoc.8" ;;
+  "man/amverify.8" ) CONFIG_FILES="$CONFIG_FILES man/amverify.8" ;;
+  "man/Makefile" ) CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+  "man/amstatus.8" ) CONFIG_FILES="$CONFIG_FILES man/amstatus.8" ;;
+  "man/amreport.8" ) CONFIG_FILES="$CONFIG_FILES man/amreport.8" ;;
+  "man/amgetconf.8" ) CONFIG_FILES="$CONFIG_FILES man/amgetconf.8" ;;
+  "man/amverifyrun.8" ) CONFIG_FILES="$CONFIG_FILES man/amverifyrun.8" ;;
+  "man/amtapetype.8" ) CONFIG_FILES="$CONFIG_FILES man/amtapetype.8" ;;
+  "docs/Makefile" ) CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
+  "recover-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES recover-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" ;;
+  "server-src/amdump.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amdump.sh" ;;
+  "server-src/amfreetapes.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amfreetapes.sh" ;;
+  "server-src/amoverview.pl" ) CONFIG_FILES="$CONFIG_FILES server-src/amoverview.pl" ;;
+  "server-src/amrmtape.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amrmtape.sh" ;;
+  "server-src/amtoc.pl" ) CONFIG_FILES="$CONFIG_FILES server-src/amtoc.pl" ;;
+  "server-src/amverify.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amverify.sh" ;;
+  "server-src/Makefile" ) CONFIG_FILES="$CONFIG_FILES server-src/Makefile" ;;
+  "server-src/amstatus.pl" ) CONFIG_FILES="$CONFIG_FILES server-src/amstatus.pl" ;;
+  "server-src/amverifyrun.sh" ) CONFIG_FILES="$CONFIG_FILES server-src/amverifyrun.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" ;;
+  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+  "$ac_stdint_h" ) CONFIG_COMMANDS="$CONFIG_COMMANDS $ac_stdint_h" ;;
+  "config/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config/config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@CONFIGURE_COMMAND@,$CONFIGURE_COMMAND,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@SNAPSHOT_STAMP@,$SNAPSHOT_STAMP,;t t
+s,@VERSION_MAJOR@,$VERSION_MAJOR,;t t
+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,@CONFIG_DIR@,$CONFIG_DIR,;t t
+s,@USE_VERSION_SUFFIXES@,$USE_VERSION_SUFFIXES,;t t
+s,@CLIENT_SCRIPTS_OPT@,$CLIENT_SCRIPTS_OPT,;t t
+s,@DEFAULT_SERVER@,$DEFAULT_SERVER,;t t
+s,@CLIENT_LOGIN@,$CLIENT_LOGIN,;t t
+s,@SETUID_GROUP@,$SETUID_GROUP,;t t
+s,@BINARY_OWNER@,$BINARY_OWNER,;t t
+s,@DEFAULT_CONFIG@,$DEFAULT_CONFIG,;t t
+s,@DEFAULT_TAPE_SERVER@,$DEFAULT_TAPE_SERVER,;t t
+s,@DEFAULT_TAPE_DEVICE@,$DEFAULT_TAPE_DEVICE,;t t
+s,@DEFAULT_RAW_TAPE_DEVICE@,$DEFAULT_RAW_TAPE_DEVICE,;t t
+s,@DEFAULT_CHANGER_DEVICE@,$DEFAULT_CHANGER_DEVICE,;t t
+s,@GNUTAR_LISTED_INCREMENTAL_DIRX@,$GNUTAR_LISTED_INCREMENTAL_DIRX,;t t
+s,@MAXTAPEBLOCKSIZE@,$MAXTAPEBLOCKSIZE,;t t
+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
+s,@CAT@,$CAT,;t t
+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
+s,@MAILER@,$MAILER,;t t
+s,@MT@,$MT,;t t
+s,@CHIO@,$CHIO,;t t
+s,@CHS@,$CHS,;t t
+s,@MTX@,$MTX,;t t
+s,@MCUTIL@,$MCUTIL,;t t
+s,@PRINT@,$PRINT,;t t
+s,@PCAT@,$PCAT,;t t
+s,@PERL@,$PERL,;t t
+s,@DUMP@,$DUMP,;t t
+s,@RESTORE@,$RESTORE,;t t
+s,@XFSDUMP@,$XFSDUMP,;t t
+s,@XFSRESTORE@,$XFSRESTORE,;t t
+s,@VXDUMP@,$VXDUMP,;t t
+s,@VXRESTORE@,$VXRESTORE,;t t
+s,@VDUMP@,$VDUMP,;t t
+s,@VRESTORE@,$VRESTORE,;t t
+s,@AMPLOT_COMPRESS@,$AMPLOT_COMPRESS,;t t
+s,@AMPLOT_CAT_GZIP@,$AMPLOT_CAT_GZIP,;t t
+s,@AMPLOT_CAT_COMPRESS@,$AMPLOT_CAT_COMPRESS,;t t
+s,@AMPLOT_CAT_PACK@,$AMPLOT_CAT_PACK,;t t
+s,@LN_S@,$LN_S,;t t
+s,@ECHO@,$ECHO,;t t
+s,@ac_ct_AR@,$ac_ct_AR,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@CXXDEPMODE@,$CXXDEPMODE,;t t
+s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t
+s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t
+s,@CXXCPP@,$CXXCPP,;t t
+s,@F77@,$F77,;t t
+s,@FFLAGS@,$FFLAGS,;t t
+s,@ac_ct_F77@,$ac_ct_F77,;t t
+s,@LIBTOOL@,$LIBTOOL,;t t
+s,@LIBTOOL_DEPS@,$LIBTOOL_DEPS,;t t
+s,@LEX@,$LEX,;t t
+s,@LEXLIB@,$LEXLIB,;t t
+s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t
+s,@READLINE_LIBS@,$READLINE_LIBS,;t t
+s,@DB_EXT@,$DB_EXT,;t t
+s,@ALLOCA@,$ALLOCA,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@ac_n@,$ac_n,;t t
+s,@ac_c@,$ac_c,;t t
+s,@WANT_CLIENT_TRUE@,$WANT_CLIENT_TRUE,;t t
+s,@WANT_CLIENT_FALSE@,$WANT_CLIENT_FALSE,;t t
+s,@WANT_SAMBA_TRUE@,$WANT_SAMBA_TRUE,;t t
+s,@WANT_SAMBA_FALSE@,$WANT_SAMBA_FALSE,;t t
+s,@WANT_RESTORE_TRUE@,$WANT_RESTORE_TRUE,;t t
+s,@WANT_RESTORE_FALSE@,$WANT_RESTORE_FALSE,;t t
+s,@WANT_SERVER_TRUE@,$WANT_SERVER_TRUE,;t t
+s,@WANT_SERVER_FALSE@,$WANT_SERVER_FALSE,;t t
+s,@WANT_RECOVER_TRUE@,$WANT_RECOVER_TRUE,;t t
+s,@WANT_RECOVER_FALSE@,$WANT_RECOVER_FALSE,;t t
+s,@WANT_TAPE_TRUE@,$WANT_TAPE_TRUE,;t t
+s,@WANT_TAPE_FALSE@,$WANT_TAPE_FALSE,;t t
+s,@WANT_AMPLOT_TRUE@,$WANT_AMPLOT_TRUE,;t t
+s,@WANT_AMPLOT_FALSE@,$WANT_AMPLOT_FALSE,;t t
+s,@WANT_CHG_SCSI_TRUE@,$WANT_CHG_SCSI_TRUE,;t t
+s,@WANT_CHG_SCSI_FALSE@,$WANT_CHG_SCSI_FALSE,;t t
+s,@WANT_CHIO_SCSI_TRUE@,$WANT_CHIO_SCSI_TRUE,;t t
+s,@WANT_CHIO_SCSI_FALSE@,$WANT_CHIO_SCSI_FALSE,;t t
+s,@WANT_RUNTIME_PSEUDO_RELOC_TRUE@,$WANT_RUNTIME_PSEUDO_RELOC_TRUE,;t t
+s,@WANT_RUNTIME_PSEUDO_RELOC_FALSE@,$WANT_RUNTIME_PSEUDO_RELOC_FALSE,;t t
+s,@WANT_SETUID_CLIENT_TRUE@,$WANT_SETUID_CLIENT_TRUE,;t t
+s,@WANT_SETUID_CLIENT_FALSE@,$WANT_SETUID_CLIENT_FALSE,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+s,@LTALLOCA@,$LTALLOCA,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                    sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([   ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[        ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([   ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+       cat >$tmp/stdin
+       ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+       ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+        # Absolute (can't be DOS-style, as IFS=:)
+        test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        # Do quote $f, to prevent DOS paths from being IFS'd.
+        echo "$f";;
+      *) # Relative
+        if test -f "$f"; then
+          # Build tree
+          echo "$f"
+        elif test -f "$srcdir/$f"; then
+          # Source tree
+          echo "$srcdir/$f"
+        else
+          # /dev/null tree
+          { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+        fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[      ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[    ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[     ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[     ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[     ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_file" : 'X\(//\)[^/]' \| \
+        X"$ac_file" : 'X\(//\)$' \| \
+        X"$ac_file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X$ac_file : 'X\(//\)[^/]' \| \
+        X$ac_file : 'X\(//\)$' \| \
+        X$ac_file : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_dest" : 'X\(//\)[^/]' \| \
+        X"$ac_dest" : 'X\(//\)$' \| \
+        X"$ac_dest" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+  case $ac_dest in
+    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$mf" : 'X\(//\)[^/]' \| \
+        X"$mf" : 'X\(//\)$' \| \
+        X"$mf" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$file" : 'X\(//\)[^/]' \| \
+        X"$file" : 'X\(//\)$' \| \
+        X"$file" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    { if $as_mkdir_p; then
+    mkdir -p $dirpart/$fdir
+  else
+    as_dir=$dirpart/$fdir
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+ ;;
+    $ac_stdint_h )
+{ echo "$as_me:$LINENO: creating $ac_stdint_h : $_ac_stdint_h" >&5
+echo "$as_me: creating $ac_stdint_h : $_ac_stdint_h" >&6;}
+ac_stdint=$tmp/_stdint.h
+
+echo "#ifndef" $_ac_stdint_h >$ac_stdint
+echo "#define" $_ac_stdint_h "1" >>$ac_stdint
+echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint
+echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint
+echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_t" != "_" ; then
+echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint
+fi
+
+cat >>$ac_stdint <<STDINT_EOF
+
+/* ................... shortcircuit part ........................... */
+
+#if defined HAVE_STDINT_H || defined _STDINT_HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <stddef.h>
+
+/* .................... configured part ............................ */
+
+STDINT_EOF
+
+echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint
+if test "_$ac_cv_header_stdint_x" != "_" ; then
+  ac_header="$ac_cv_header_stdint_x"
+  echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint
+fi
+
+echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_o" != "_" ; then
+  ac_header="$ac_cv_header_stdint_o"
+  echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint
+fi
+
+echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint
+if  test "_$ac_cv_header_stdint_u" != "_" ; then
+  ac_header="$ac_cv_header_stdint_u"
+  echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint
+else
+  echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint
+fi
+
+echo "" >>$ac_stdint
+
+if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then
+  echo "#include <$ac_header>" >>$ac_stdint
+  echo "" >>$ac_stdint
+fi fi
+
+echo "/* which 64bit typedef has been found */" >>$ac_stdint
+if test "$ac_cv_type_uint64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_UINT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint
+fi
+if test "$ac_cv_type_u_int64_t" = "yes" ; then
+echo "#define   _STDINT_HAVE_U_INT64_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* which type model has been detected */" >>$ac_stdint
+if test "_$ac_cv_stdint_char_model" != "_" ; then
+echo "#define   _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint
+echo "#define   _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint
+else
+echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint
+echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+echo "/* whether int_least types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_least32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_LEAST32_T" "1"  >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint
+fi
+echo "/* whether int_fast types were detected */" >>$ac_stdint
+if test "$ac_cv_type_int_fast32_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint
+fi
+echo "/* whether intmax_t type was detected */" >>$ac_stdint
+if test "$ac_cv_type_intmax_t" = "yes"; then
+echo "#define   _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint
+else
+echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint
+fi
+echo "" >>$ac_stdint
+
+  cat >>$ac_stdint <<STDINT_EOF
+/* .................... detections part ............................ */
+
+/* whether we need to define bitspecific types from compiler base types */
+#ifndef _STDINT_HEADER_INTPTR
+#ifndef _STDINT_HEADER_UINT32
+#ifndef _STDINT_HEADER_U_INT32
+#define _STDINT_NEED_INT_MODEL_T
+#else
+#define _STDINT_HAVE_U_INT_TYPES
+#endif
+#endif
+#endif
+
+#ifdef _STDINT_HAVE_U_INT_TYPES
+#undef _STDINT_NEED_INT_MODEL_T
+#endif
+
+#ifdef  _STDINT_CHAR_MODEL
+#if     _STDINT_CHAR_MODEL+0 == 122 || _STDINT_CHAR_MODEL+0 == 124
+#ifndef _STDINT_BYTE_MODEL
+#define _STDINT_BYTE_MODEL 12
+#endif
+#endif
+#endif
+
+#ifndef _STDINT_HAVE_INT_LEAST32_T
+#define _STDINT_NEED_INT_LEAST_T
+#endif
+
+#ifndef _STDINT_HAVE_INT_FAST32_T
+#define _STDINT_NEED_INT_FAST_T
+#endif
+
+#ifndef _STDINT_HEADER_INTPTR
+#define _STDINT_NEED_INTPTR_T
+#ifndef _STDINT_HAVE_INTMAX_T
+#define _STDINT_NEED_INTMAX_T
+#endif
+#endif
+
+
+/* .................... definition part ............................ */
+
+/* some system headers have good uint64_t */
+#ifndef _HAVE_UINT64_T
+#if     defined _STDINT_HAVE_UINT64_T  || defined HAVE_UINT64_T
+#define _HAVE_UINT64_T
+#elif   defined _STDINT_HAVE_U_INT64_T || defined HAVE_U_INT64_T
+#define _HAVE_UINT64_T
+typedef u_int64_t uint64_t;
+#endif
+#endif
+
+#ifndef _HAVE_UINT64_T
+/* .. here are some common heuristics using compiler runtime specifics */
+#if defined __STDC_VERSION__ && defined __STDC_VERSION__ >= 199901L
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+
+#elif !defined __STRICT_ANSI__
+#if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__
+#define _HAVE_UINT64_T
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__
+/* note: all ELF-systems seem to have loff-support which needs 64-bit */
+#if !defined _NO_LONGLONG
+#define _HAVE_UINT64_T
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+#endif
+
+#elif defined __alpha || (defined __mips && defined _ABIN32)
+#if !defined _NO_LONGLONG
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#endif
+  /* compiler/cpu type to define int64_t */
+#endif
+#endif
+#endif
+
+#if defined _STDINT_HAVE_U_INT_TYPES
+/* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+
+/* glibc compatibility */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INT_MODEL_T
+/* we must guess all the basic types. Apart from byte-adressable system, */
+/* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */
+/* (btw, those nibble-addressable systems are way off, or so we assume) */
+
+
+#if defined _STDINT_BYTE_MODEL
+#if _STDINT_LONG_MODEL+0 == 242
+/* 2:4:2 =  IP16 = a normal 16-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned long   uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          long    int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444
+/* 2:4:4 =  LP32 = a 32-bit system derived from a 16-bit */
+/* 4:4:4 = ILP32 = a normal 32-bit system                */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488
+/* 4:8:4 =  IP32 = a 32-bit system prepared for 64-bit    */
+/* 4:8:8 =  LP64 = a normal 64-bit system                 */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* this system has a "long" of 64bit */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long   uint64_t;
+typedef          long    int64_t;
+#endif
+#elif _STDINT_LONG_MODEL+0 == 448
+/*      LLP64   a 64-bit system derived from a 32-bit system */
+typedef unsigned char   uint8_t;
+typedef unsigned short  uint16_t;
+typedef unsigned int    uint32_t;
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef          char    int8_t;
+typedef          short   int16_t;
+typedef          int     int32_t;
+#endif
+/* assuming the system has a "long long" */
+#ifndef _HAVE_UINT64_T
+#define _HAVE_UINT64_T
+typedef unsigned long long uint64_t;
+typedef          long long  int64_t;
+#endif
+#else
+#define _STDINT_NO_INT32_T
+#endif
+#else
+#define _STDINT_NO_INT8_T
+#define _STDINT_NO_INT32_T
+#endif
+#endif
+
+/*
+ * quote from SunOS-5.8 sys/inttypes.h:
+ * Use at your own risk.  As of February 1996, the committee is squarely
+ * behind the fixed sized types; the "least" and "fast" types are still being
+ * discussed.  The probability that the "fast" types may be removed before
+ * the standard is finalized is high enough that they are not currently
+ * implemented.
+ */
+
+#if defined _STDINT_NEED_INT_LEAST_T
+typedef  int8_t    int_least8_t;
+typedef  int16_t   int_least16_t;
+typedef  int32_t   int_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_least64_t;
+#endif
+
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_least64_t;
+#endif
+  /* least types */
+#endif
+
+#if defined _STDINT_NEED_INT_FAST_T
+typedef  int8_t    int_fast8_t;
+typedef  int       int_fast16_t;
+typedef  int32_t   int_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef  int64_t   int_fast64_t;
+#endif
+
+typedef uint8_t   uint_fast8_t;
+typedef unsigned  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+#ifdef _HAVE_UINT64_T
+typedef uint64_t  uint_fast64_t;
+#endif
+  /* fast types */
+#endif
+
+#ifdef _STDINT_NEED_INTMAX_T
+#ifdef _HAVE_UINT64_T
+typedef  int64_t       intmax_t;
+typedef uint64_t      uintmax_t;
+#else
+typedef          long  intmax_t;
+typedef unsigned long uintmax_t;
+#endif
+#endif
+
+#ifdef _STDINT_NEED_INTPTR_T
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+/* we encourage using "long" to store pointer values, never use "int" ! */
+#if   _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484
+typedef  unsinged int   uintptr_t;
+typedef           int    intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T
+typedef        uint64_t uintptr_t;
+typedef         int64_t  intptr_t;
+#else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */
+typedef  unsigned long  uintptr_t;
+typedef           long   intptr_t;
+#endif
+#endif
+#endif
+
+  /* shortcircuit*/
+#endif
+  /* once */
+#endif
+#endif
+STDINT_EOF
+    if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then
+      { echo "$as_me:$LINENO: $ac_stdint_h is unchanged" >&5
+echo "$as_me: $ac_stdint_h is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_stdint_h") 2>/dev/null ||
+$as_expr X"$ac_stdint_h" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$ac_stdint_h" : 'X\(//\)[^/]' \| \
+        X"$ac_stdint_h" : 'X\(//\)$' \| \
+        X"$ac_stdint_h" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_stdint_h" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+        X"$as_dir" : 'X\(//\)[^/]' \| \
+        X"$as_dir" : 'X\(//\)$' \| \
+        X"$as_dir" : 'X\(/\)' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_stdint_h
+      mv $ac_stdint $ac_stdint_h
+    fi
+ ;;
+  esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..850c2ef
--- /dev/null
@@ -0,0 +1,2825 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT
+AC_CONFIG_SRCDIR([common-src/amanda.h])
+AC_CONFIG_AUX_DIR(config)
+AC_CANONICAL_TARGET([])
+
+
+CONFIGURE_COMMAND="'$0'"
+for arg in "$@"; do
+  CONFIGURE_COMMAND="$CONFIGURE_COMMAND '$arg'"
+done
+AC_DEFINE_UNQUOTED(CONFIGURE_COMMAND,"$CONFIGURE_COMMAND",
+         [Saves the original ./configure command line arguments])
+AC_SUBST(CONFIGURE_COMMAND)
+
+AM_INIT_AUTOMAKE(amanda, 2.4.4p3)
+AM_CONFIG_HEADER(config/config.h)
+
+AC_PREREQ(2.57)                dnl Minimum Autoconf version required.
+
+if test -f "$srcdir/SNAPSHOT"; then
+  cat < "$srcdir/SNAPSHOT"
+changequote(,)
+  snapdate=`sed -n '/^Snapshot Date: \([0-9]*\)/ s//\1/p' < $srcdir/SNAPSHOT`
+changequote([,])
+  test -z "$snapdate" || VERSION="$VERSION-$snapdate"
+  SNAPSHOT_STAMP=SNAPSHOT
+else
+  SNAPSHOT_STAMP=
+fi
+AC_SUBST(SNAPSHOT_STAMP)
+
+if test -f config.local; then
+    echo "running local script ./config.local"
+    . ./config.local
+fi
+
+dnl
+dnl Set the version number of this release of Amanda from the VERSION
+dnl string, which is set in AM_INIT_AUTOMAKE.
+dnl
+changequote(,)
+VERSION_MAJOR=`expr "$VERSION" : '\([0-9]*\)'`
+VERSION_MINOR=`expr "$VERSION" : '[0-9]*\.\([0-9]*\)'`
+VERSION_PATCH=`expr "$VERSION" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+VERSION_COMMENT=\"`expr "$VERSION" : '[0-9]*\.[0-9]*\.[0-9]*\(.*\)'`\"
+changequote([,])
+
+VERSION_SUFFIX="$VERSION"
+AC_SUBST(VERSION_MAJOR)
+AC_SUBST(VERSION_MINOR)
+AC_SUBST(VERSION_PATCH)
+AC_SUBST(VERSION_COMMENT)
+AC_SUBST(VERSION_SUFFIX)
+
+dnl
+dnl runtime and compile time
+dnl
+SYSPATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb:/usr/bsd:/etc:/usr/etc"
+LOCPATH=`(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+    eval echo "$libexecdir:$PATH:/usr/local/sbin:/usr/local/bin"
+)`
+SYSLOCPATH="$SYSPATH:$LOCPATH"
+LOCSYSPATH="$LOCPATH:$SYSPATH"
+
+AC_ARG_WITH(includes,
+    [  --with-includes=DIR    site header files for readline, etc in DIR],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-includes option.])
+         ;;
+       esac
+       INCLUDE_DIRS="$withval"
+    ])
+
+if test "$INCLUDE_DIRS"; then
+       for dir in $INCLUDE_DIRS; do
+           if test -d "$dir"; then
+               AMANDA_CPPFLAGS="$AMANDA_CPPFLAGS -I$dir"
+           else
+               AC_MSG_WARN([*** Include directory $dir does not exist.])
+           fi
+       done
+fi
+
+AC_ARG_WITH(libraries,
+    [  --with-libraries=DIR   site library directories for readline, etc in DIR],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-libraries option.])
+         ;;
+       esac
+       LIBRARY_DIRS="$withval"
+    ])
+
+if test "$LIBRARY_DIRS"; then
+       for dir in $LIBRARY_DIRS; do
+           if test -d "$dir"; then
+               case "$target" in
+                 *-solaris2*)
+                       AMANDA_LDFLAGS="$AMANDA_LDFLAGS -R$dir"
+                       ;;
+               esac
+               AMANDA_LDFLAGS="$AMANDA_LDFLAGS -L$dir"
+           else
+               AC_MSG_WARN([*** Library directory $dir does not exist.])
+           fi
+       done
+fi
+
+AC_ARG_WITH(configdir,
+    [  --with-configdir=DIR   runtime config files in DIR [sysconfdir/amanda]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-configdir option.])
+         ;;
+       *) CONFIG_DIR="$withval"
+         ;;
+       esac
+    ],
+    : ${CONFIG_DIR=$sysconfdir/amanda}
+)
+CONFIG_DIR=`(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+    eval echo "$CONFIG_DIR"
+)`
+AC_DEFINE_UNQUOTED(CONFIG_DIR,"$CONFIG_DIR",
+  [The directory in which configuration directories should be created. ])
+AC_SUBST(CONFIG_DIR)
+
+AC_ARG_WITH(indexdir,
+    [  --with-indexdir        deprecated, use indexdir in amanda.conf],
+    [   AC_MSG_ERROR([*** --with-indexdir is deprecated, use indexdir in amanda.conf instead.])
+    ],)
+
+AC_ARG_WITH(dbdir,
+    [  --with-dbdir           deprecated, use infofile in amanda.conf],
+    [   AC_MSG_ERROR([*** --with-dbdir is deprecated, use infofile in amanda.conf instead.])
+    ],)
+
+AC_ARG_WITH(logdir,
+    [  --with-logdir          deprecated, use logfile in amanda.conf],
+    [   AC_MSG_ERROR([*** --with-logdir is deprecated, use logdir in amanda.conf instead.])
+    ],)
+
+AC_ARG_WITH(suffixes,
+    [  --with-suffixes        install binaries with version string appended to name],
+    USE_VERSION_SUFFIXES=$withval,
+    : ${USE_VERSION_SUFFIXES=no}
+)
+case "$USE_VERSION_SUFFIXES" in
+y | ye | yes)
+    AC_DEFINE(USE_VERSION_SUFFIXES, 1,
+       [Define to have programs use version suffixes when calling other programs.])
+
+    program_suffix="-$VERSION"
+    # This is from the output of configure.in.
+    if test "$program_transform_name" = s,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 "$program_prefix" != NONE &&
+       program_transform_name="s,^,${program_prefix},; $program_transform_name"
+    # Use a double $ so make ignores it.
+    test "$program_suffix" != NONE &&
+       program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+    # sed with no file args requires a program.
+    test "$program_transform_name" = "" && program_transform_name="s,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
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-suffixes option.])
+  ;;
+esac
+AC_SUBST(USE_VERSION_SUFFIXES)
+
+case "$target" in
+    *-hp-*)
+       CLIENT_SCRIPTS_OPT=amhpfixdevs
+       ;;
+    *-sni-sysv4)
+       CLIENT_SCRIPTS_OPT=amsinixfixdevs
+       ;;
+    *)
+       CLIENT_SCRIPTS_OPT=
+       ;;
+esac
+
+AC_SUBST(CLIENT_SCRIPTS_OPT)
+
+AC_ARG_WITH(client-only,
+    [  --with-client-only     deprecated, use --without-server],
+    [   AC_MSG_ERROR([*** --with-client-only is deprecated, use --without-server instead.])
+    ],)
+AC_ARG_WITH(server-only,
+    [  --with-server-only     deprecated, use --without-client],
+    [   AC_MSG_ERROR([*** --with-server-only is deprecated, use --without-client instead.])
+    ],)
+
+AC_ARG_WITH(client,
+    [  --without-client       do not build client stuff],
+    [
+       case "$withval" in
+       y | ye | yes) NO_CLIENT_MODE=false;;
+       n | no) NO_CLIENT_MODE=true;;
+       *)
+           AC_MSG_ERROR([*** You must not supply an argument to --with-client option.])
+         ;;
+       esac
+    ]
+)
+
+AC_ARG_WITH(server,
+    [  --without-server       do not build server stuff (set --without-restore)],
+    [
+       case "$withval" in
+       y | ye | yes) NO_SERVER_MODE=false ;;
+       n | no) NO_SERVER_MODE=true;NO_RESTORE_MODE=true;;
+       *)
+           AC_MSG_ERROR([*** You must not supply an argument to --with-server option.  Maybe you meant --with-index-server=$withval])
+         ;;
+       esac
+    ]
+)
+
+AC_ARG_WITH(restore,
+    [  --without-restore      do not build amrestore nor amidxtaped],
+    [
+       case "$withval" in
+       y | ye | yes) NO_RESTORE_MODE=false;;
+       n | no) NO_RESTORE_MODE=true;;
+       *)
+           AC_MSG_ERROR([*** You must not supply an argument to --with-restore option.])
+         ;;
+       esac
+    ]
+)
+
+AC_ARG_WITH(amrecover,
+    [  --without-amrecover    do not build amrecover],
+    [
+       case "$withval" in
+       y | ye | yes)
+           if ${NO_CLIENT_MODE-false}; then
+               AC_MSG_ERROR([*** --without-client and --with-amrecover are incompatible])
+           fi
+           NO_RECOVER_MODE=false;;
+       n | no) NO_RECOVER_MODE=true;;
+       *)
+           AC_MSG_ERROR([*** You must not supply an argument to --with-amrecover option.])
+         ;;
+       esac
+    ]
+)
+
+AC_ARG_WITH(index-server,
+   [  --with-index-server=HOST default amanda index server [`uname -n`]],
+   [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-index-server option.])
+         ;;
+       *) DEFAULT_SERVER="$withval"
+         ;;
+       esac
+   ],
+   : ${DEFAULT_SERVER=`uname -n`}
+)
+AC_DEFINE_UNQUOTED(DEFAULT_SERVER,"$DEFAULT_SERVER",
+  [This is the default Amanda index server. ])
+AC_SUBST(DEFAULT_SERVER)
+
+AC_ARG_WITH(force-uid,
+    [  --without-force-uid    do not force the uid to --with-user],
+    FORCE_USERID="$withval",
+    : ${FORCE_USERID=yes}
+)
+case "$FORCE_USERID" in
+y | ye | yes) AC_DEFINE(FORCE_USERID, 1,
+       [Define to force to another user on client machines. ])
+  ;;
+n | no) :
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-force-uid option.])
+esac
+
+AC_ARG_WITH(user,
+    [  --with-user=USER       force execution to USER on client systems [required]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-user option.])
+         ;;
+       *) CLIENT_LOGIN="$withval"
+         ;;
+       esac
+    ]
+)
+if test "x${CLIENT_LOGIN+set}" != xset; then
+    AC_MSG_ERROR([*** --with-user=USER is missing])
+fi
+AC_DEFINE_UNQUOTED(CLIENT_LOGIN,"$CLIENT_LOGIN",
+  [Define as a the user to force to on client machines. ])
+AC_SUBST(CLIENT_LOGIN)
+
+AC_ARG_WITH(group,
+    [  --with-group=GROUP     group allowed to execute setuid-root programs [required]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-group option.])
+         ;;
+       *) SETUID_GROUP="$withval"
+         ;;
+       esac
+    ]
+)
+if test "x${SETUID_GROUP+set}" != xset; then
+    AC_MSG_ERROR([*** --with-group=GROUP is missing])
+fi
+AC_SUBST(SETUID_GROUP)
+
+AC_ARG_WITH(owner,
+    [  --with-owner=USER       force ownership of files to USER [default == --with-user value]],
+    [
+        case "$withval" in
+        "" | y | ye | yes | n | no)
+            AC_MSG_ERROR([*** You must supply an argument to the --with-owner option.])
+          ;;
+        *) BINARY_OWNER="$withval"
+          ;;
+        esac
+    ]
+)
+if test "x${BINARY_OWNER+set}" != xset ; then
+   BINARY_OWNER=$CLIENT_LOGIN
+fi
+AC_DEFINE_UNQUOTED(BINARY_OWNER,"$BINARY_OWNER",
+  [Define as the user who owns installed binaries. ])
+AC_SUBST(BINARY_OWNER)
+
+AC_ARG_WITH(rundump,
+    [  --with-rundump         use rundump (setuid-root) to invoke dump],
+    [
+    case "$withval" in
+       n | no | y | ye | yes) FORCE_USE_RUNDUMP="$withval";;
+       *) AC_MSG_ERROR([*** You must not supply an argument to --with-rundump option.]);;
+    esac
+    ]
+)
+
+AC_ARG_WITH(config,
+   [  --with-config=CONFIG   default configuration [DailySet1]],
+   [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-config option.])
+         ;;
+       *) DEFAULT_CONFIG="$withval"
+         ;;
+       esac
+   ],
+   : ${DEFAULT_CONFIG=DailySet1}
+)
+AC_DEFINE_UNQUOTED(DEFAULT_CONFIG,"$DEFAULT_CONFIG",
+  [This is the default Amanda configuration. ])
+AC_SUBST(DEFAULT_CONFIG)
+
+AC_ARG_WITH(tape-server,
+    [  --with-tape-server=HOST default restoring tape server is HOST [same as --with-index-server]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-tape-server option.])
+         ;;
+       *) DEFAULT_TAPE_SERVER="$withval"
+         ;;
+       esac
+    ],
+    : ${DEFAULT_TAPE_SERVER=$DEFAULT_SERVER}
+)
+AC_DEFINE_UNQUOTED(DEFAULT_TAPE_SERVER,"$DEFAULT_TAPE_SERVER",[This is the default restoring Amanda tape server. ])
+AC_SUBST(DEFAULT_TAPE_SERVER)
+
+AC_ARG_WITH(tape-device,
+    [  --with-tape-device=ARG restoring tape server HOST's no rewinding tape drive],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-tape-device option.])
+         ;;
+       *) DEFAULT_TAPE_DEVICE="$withval"
+         ;;
+       esac
+    ],
+    [
+       if test -z "$DEFAULT_TAPE_DEVICE"; then
+           AC_MSG_CHECKING(for non-rewinding tape device)
+           dnl Check for the /dev/rmt directory and use what's in there.
+           dnl Otherwise look for tape devices in /dev.  For the devices
+           dnl in /dev/rmt, we want to use the Berkeley behavior of
+           dnl reading the first record of the next tape file after 0
+           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=/dev/null
+           nr_tape_dev=/dev/null
+           if test -d /dev/rmt; then
+
+               dnl See if we can find two devices, one being the norewind
+               dnl version of the other.  Devices in this directory are
+               dnl normally a digit followed by some characters.  We also
+               dnl want the Berkely behavior, since Amanda needs it for
+               dnl amrestore.
+
+               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
+               dnl Look for tape devices in /dev.
+               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
+           AC_MSG_RESULT($DEFAULT_TAPE_DEVICE)
+       fi
+    ]
+)
+
+if test -z "$DEFAULT_TAPE_DEVICE"; then
+    DEFAULT_TAPE_DEVICE=/dev/null
+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],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-ftape-rawdevice option.])
+         ;;
+       *) DEFAULT_RAW_TAPE_DEVICE="$withval"
+         ;;
+       esac
+    ],
+    [
+       if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
+           AC_MSG_CHECKING(for raw ftape device)
+           dnl Look for tape devices in /dev.  
+           raw_tape_dev=/dev/null
+               dnl Look for tape devices in /dev.
+               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
+           AC_MSG_RESULT($DEFAULT_RAW_TAPE_DEVICE)
+       fi
+    ]
+)
+
+if test -z "$DEFAULT_RAW_TAPE_DEVICE"; then
+    DEFAULT_RAW_TAPE_DEVICE=/dev/null
+fi
+
+AC_DEFINE_UNQUOTED(DEFAULT_RAW_TAPE_DEVICE,"$DEFAULT_RAW_TAPE_DEVICE",[For Linux systems with floppy tapes: 
+ * QIC volume table support via raw tape device. ])
+AC_SUBST(DEFAULT_RAW_TAPE_DEVICE)
+
+AC_ARG_WITH(rew-tape,
+    [  --with-rew-tape        deprecated, use --with-tape-device],
+    [   AC_MSG_ERROR([*** --with-rew-tape is deprecated, use --with-tape-device instead.])
+    ],)
+
+AC_ARG_WITH(norew-tape,
+    [  --with-norew-tape=ARG  deprecated, use --with-tape-device],
+    [   AC_MSG_ERROR([*** --with-norew-tape is deprecated, use --with-tape-device instead.])
+    ],)
+
+AC_ARG_WITH(changer-device,
+    [  --with-changer-device=ARG default tape changer device [/dev/ch0 if it exists]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-changer-device option.])
+         ;;
+       *) DEFAULT_CHANGER_DEVICE="$withval"
+         ;;
+       esac
+    ],
+    [
+       if test -z "$DEFAULT_CHANGER_DEVICE" &&
+          test -f /dev/ch0; then
+           DEFAULT_CHANGER_DEVICE=/dev/ch0
+       fi
+    ]
+)
+
+if test -z "$DEFAULT_CHANGER_DEVICE"; then
+    DEFAULT_CHANGER_DEVICE=/dev/null
+fi
+
+AC_DEFINE_UNQUOTED(DEFAULT_CHANGER_DEVICE,"$DEFAULT_CHANGER_DEVICE",[This is the default changer device. ])
+AC_SUBST(DEFAULT_CHANGER_DEVICE)
+
+AC_ARG_WITH(fqdn,
+    [  --with-fqdn            use FQDN's to backup multiple networks],
+    USE_FQDN=$withval,
+    : ${USE_FQDN=no}
+)
+case "$USE_FQDN" in
+n | no) : ;;
+y |  ye | yes) AC_DEFINE(USE_FQDN,1,[Define for backups being done on a multiple networks and FQDNs are used. ])
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-fqdn option.])
+  ;;
+esac
+
+AC_ARG_WITH(broken-fsf,
+    [  --with-broken-fsf      only enable if tape fsf calls fail mid-file],
+    HAVE_BROKEN_FSF=$withval,
+    : ${HAVE_BROKEN_FSF=no}
+)
+case "$HAVE_BROKEN_FSF" in
+n | no) : ;;
+y |  ye | yes) AC_DEFINE(HAVE_BROKEN_FSF,1,[Define this if issuing a fsf on a tape fails when you are not at a tape
+ * mark, for instance, if amrecover gives I/O errors when skipping.
+])
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-broken-fsf option.])
+  ;;
+esac
+
+AC_ARG_WITH(gnutar,
+    [  --with-gnutar[=PROG]     use PROG as GNU tar executable [default: looks for one]],
+    [
+       case "$withval" in
+           /*) GNUTAR="$withval";;
+           y|ye|yes) :;;
+           n|no) GNUTAR=;;
+           *)  AC_MSG_ERROR([*** You must supply a full pathname to --with-gnutar]);;
+       esac
+    ]
+)
+
+AC_ARG_WITH(qde,
+    [   --with-qde                use quick-and-dirty estimates for gnutar ],
+    USE_QUICK_AND_DIRTY_ESTIMATES=$withval,
+    : ${USE_QUICK_AND_DIRTY_ESTIMATES=no}
+)
+case "$USE_QUICK_AND_DIRTY_ESTIMATES" in
+n | no) : USE_QUICK_AND_DIRTY_ESTIMATES=no;;
+y |  ye | yes) : USE_QUICK_AND_DIRTY_ESTIMATES=yes
+       AC_DEFINE(USE_QUICK_AND_DIRTY_ESTIMATES,1,[ Define if you want to use amqde instead of gnutar for estimates ])
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-qde option.])
+  ;;
+esac
+
+
+AC_ARG_WITH(smbclient,
+    [  --with-smbclient[=PROG]   use PROG as Samba's smbclient executable [default: looks for one]],
+    [
+       case "$withval" in
+           /*) SAMBA_CLIENT="$withval";;
+           y|ye|yes) :;;
+           n|no) SAMBA_CLIENT="no";;
+           *)  AC_MSG_ERROR([*** You must supply a full pathname to --with-smbclient]);;
+       esac
+    ]
+)
+
+AC_ARG_WITH(samba-user,
+   [  --with-samba-user was deprecated],
+   [    AC_MSG_ERROR([*** The samba-user option was deprecated, the username go in the amandapass])
+   ]
+)
+
+AC_ARG_WITH(gnutar-listdir,
+   [  --with-gnutar-listdir=DIR  gnutar directory lists go in DIR [localstatedir/amanda/gnutar-lists]],
+   [
+       case "$withval" in
+           n | no)             unset GNUTAR_LISTDIR ;;
+           y | ye | yes)       : ${GNUTAR_LISTDIR=$localstatedir/amanda/gnutar-lists} ;;
+           /*)                 GNUTAR_LISTDIR="$withval" ;;
+           *)                  AC_MSG_ERROR([*** You must supply a full pathname to --with-gnutar-listdir])
+       esac
+    ],
+    : ${GNUTAR_LISTDIR=$localstatedir/amanda/gnutar-lists}
+)
+if test "$GNUTAR_LISTDIR"; then
+    GNUTAR_LISTDIR=`(
+        test "x$prefix" = xNONE && prefix=$ac_default_prefix
+        eval echo "$GNUTAR_LISTDIR"
+    )`
+    AC_DEFINE_UNQUOTED(GNUTAR_LISTED_INCREMENTAL_DIR,"$GNUTAR_LISTDIR",[The directory in which GNU tar should store directory lists for incrementals. ])
+    GNUTAR_LISTED_INCREMENTAL_DIRX=$GNUTAR_LISTDIR
+else
+    GNUTAR_LISTED_INCREMENTAL_DIRX=
+fi
+AC_SUBST(GNUTAR_LISTED_INCREMENTAL_DIRX)
+
+AC_ARG_WITH(gnutar-listed-incremental,
+   [  --with-gnutar-listed-incremental was deprecated, use --with-gnutar-listdir],
+   [    AC_MSG_ERROR([*** The gnutar-listed-incremental option was deprecated, use gnutar-listdir instead])
+   ]
+)
+
+AC_ARG_WITH(bsd-security,
+    [  --without-bsd-security do not use BSD rsh/rlogin style security],
+    BSD_SECURITY=$withval,
+    : ${BSD_SECURITY=yes}
+)
+case "$BSD_SECURITY" in
+n | no) : ;;
+y |  ye | yes) AC_DEFINE(BSD_SECURITY,1,[Define to use BSD .rhosts/.amandahosts security. ])
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-bsd-security option.])
+  ;;
+esac
+
+AC_ARG_WITH(amandahosts,
+    [  --without-amandahosts  use .rhosts instead of .amandahosts],
+    USE_AMANDAHOSTS=$withval,
+    : ${USE_AMANDAHOSTS=yes}
+)
+case "$USE_AMANDAHOSTS" in
+n | no) : ;;
+y |  ye | yes) :
+  case "$BSD_SECURITY" in
+  y | ye | yes) AC_DEFINE(USE_AMANDAHOSTS,1,[Define if you want to use the .amandahosts for BSD security. ])
+    ;;
+  esac
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-amandahosts option.])
+  ;;
+esac
+
+dnl Specify --with-krb4-security if Kerberos software is in somewhere
+dnl other than the listed KRB4_SPOTS.  We only compile kerberos support in
+dnl if the right files are there.
+
+: ${KRB4_SPOTS="/usr/kerberos /usr/cygnus /usr /opt/kerberos"}
+
+AC_ARG_WITH(krb4-security,
+    [  --with-krb4-security=DIR   Location of Kerberos software [/usr/kerberos /usr/cygnus /usr /opt/kerberos]],
+    KRB4_SECURITY="$withval",
+    : ${KRB4_SECURITY=no}
+)
+
+case "$KRB4_SECURITY" in
+n | no) KRB4_SECURITY=no ;;
+y | ye | yes) : ;;
+*) KRB4_SPOTS="$KRB4_SECURITY"
+   KRB4_SECURITY=yes
+   ;;
+esac
+
+AC_MSG_CHECKING(for Kerberos and Amanda kerberos4 bits)
+if test "${KRB4_SECURITY}" = yes -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.
+           #
+           AC_MSG_RESULT(found in $dir)
+           KRB4_SECURITY=yes
+           AC_DEFINE(KRB4_SECURITY, 1, [Enable Kerberos security. ])
+           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
+           if test -f ${dir}/lib/libroken.a ; then
+               KRB4LIBS="$KRB4LIBS -lroken"
+           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.
+           #
+           AC_MSG_RESULT(found in $dir)
+           KRB4_SECURITY=yes
+           AC_DEFINE(KRB4_SECURITY, 1, [Enable Kerberos security. ])
+           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
+       elif test -f ${dir}/lib/libkrb4.dylib &&
+            test -f ${dir}/lib/libcrypto.dylib &&
+            test -f ${dir}/lib/libdes425.dylib ; then
+           #
+           # This is Kerberos 5 with Kerberos 4 back-support for Mac OS X.
+           #
+           AC_MSG_RESULT(found in $dir)
+           KRB4_SECURITY=yes
+           AC_DEFINE(KRB4_SECURITY, 1, [Enable Kerberos security. ])
+           KRB4INCLUDES="-I$dir/include -I$dir/include/kerberosIV"
+           KRB4LDFLAGS=-L$dir/lib
+           if test -f ${dir}/lib/libkrb5.dylib &&
+               test -f ${dir}/lib/libcom_err.dylib; then
+               KRB4LIBS="-lkrb4 -lkrb5 -lcrypto -ldes425 -lcom_err"
+           else
+               KRB4LIBS="-lkrb4 -lcrypto -ldes425"
+           fi
+           break
+       fi
+    done
+
+    if test "$KRB4LDFLAGS" = "" ; then
+       AC_MSG_ERROR([*** Kerberos IV not found.])
+    fi
+else
+    AC_MSG_RESULT(no)
+fi
+
+AC_ARG_WITH(server-principal,
+    [    --with-server-principal=ARG    server host principal  ["amanda"]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-server-principal option.])
+         ;;
+       *)
+           SERVER_HOST_PRINCIPLE="$withval"
+         ;;
+       esac
+    ],
+    : ${SERVER_HOST_PRINCIPLE="amanda"}
+)
+AC_DEFINE_UNQUOTED(SERVER_HOST_PRINCIPLE,"$SERVER_HOST_PRINCIPLE",[The Kerberos server principle. ])
+
+AC_ARG_WITH(server-instance,
+    [    --with-server-instance=ARG     server host instance   ["amanda"]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-server-instance option.])
+         ;;
+       *) SERVER_HOST_INSTANCE="$withval"
+         ;;
+       esac
+    ],
+    : ${SERVER_HOST_INSTANCE="amanda"}
+)
+AC_DEFINE_UNQUOTED(SERVER_HOST_INSTANCE,"$SERVER_HOST_INSTANCE",[The Kerberos server instance. ])
+
+AC_ARG_WITH(server-keyfile,
+    [    --with-server-keyfile=ARG      server host key file   ["/.amanda"]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-server-keyfile option.])
+         ;;
+       *) SERVER_HOST_KEY_FILE="$withval"
+         ;;
+       esac
+    ],
+    : ${SERVER_HOST_KEY_FILE="/.amanda"}
+)
+AC_DEFINE_UNQUOTED(SERVER_HOST_KEY_FILE,"$SERVER_HOST_KEY_FILE",[The Kerberos server key file. ])
+
+AC_ARG_WITH(client-principal,
+    [    --with-client-principal=ARG    client host principal  ["rcmd"]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-client-principal option.])
+         ;;
+       *) CLIENT_HOST_PRINCIPLE="$withval"
+         ;;
+       esac
+    ],
+    : ${CLIENT_HOST_PRINCIPLE="rcmd"}
+)
+AC_DEFINE_UNQUOTED(CLIENT_HOST_PRINCIPLE,"$CLIENT_HOST_PRINCIPLE",[The Kerberos client host principle. ])
+
+AC_ARG_WITH(client-instance,
+    [    --with-client-instance=ARG     client host instance   [HOSTNAME_INSTANCE]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-client-instance option.])
+         ;;
+       *) CLIENT_HOST_INSTANCE="$withval"
+         ;;
+       esac
+    ],
+    : ${CLIENT_HOST_INSTANCE=HOSTNAME_INSTANCE}
+)
+AC_DEFINE_UNQUOTED(CLIENT_HOST_INSTANCE,$CLIENT_HOST_INSTANCE,[The Kerberos client host instance. ])
+
+AC_ARG_WITH(client-keyfile,
+    [    --with-client-keyfile=ARG      client host key file   [KEYFILE]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-client-keyfile option.])
+         ;;
+       *) CLIENT_HOST_KEY_FILE="$withval"
+         ;;
+       esac
+    ],
+    : ${CLIENT_HOST_KEY_FILE=KEYFILE}
+)
+
+# Assume it's either KEYFILE (defined in krb.h), or a string filename...
+if test "$CLIENT_HOST_KEY_FILE" != "KEYFILE"; then
+  CLIENT_HOST_KEY_FILE="\"$CLIENT_HOST_KEY_FILE\""
+fi
+
+AC_DEFINE_UNQUOTED(CLIENT_HOST_KEY_FILE,$CLIENT_HOST_KEY_FILE,[The Kerberos client host key file. ])
+
+AC_ARG_WITH(ticket-lifetime,
+    [    --with-ticket-lifetime=ARG     ticket lifetime        [128]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-ticket-lifetime option.])
+         ;;
+       *) TICKET_LIFETIME="$withval"
+         ;;
+       esac
+    ],
+    : ${TICKET_LIFETIME=128}
+)
+AC_DEFINE_UNQUOTED(TICKET_LIFETIME,$TICKET_LIFETIME,[The Kerberos ticket lifetime. ])
+
+
+AC_ARG_WITH(portrange,
+    [  --with-portrange=low,high     bind unreserved TCP server sockets to ports within this range [unlimited]],
+    [
+       TCPPORTRANGE="$withval"
+    ]
+)
+AC_ARG_WITH(tcpportrange,
+    [  --with-tcpportrange=low,high  bind unreserved TCP server sockets to ports within this range [unlimited]],
+    [
+       TCPPORTRANGE="$withval"
+    ]
+)
+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
+       AC_MSG_ERROR([*** --with-tcpportrange requires two comma-separated positive numbers])
+    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
+       AC_MSG_ERROR([*** the second TCP port number must be greater than the first in --with-tcpportrange])
+    fi
+    if test $min_tcp_port -lt 1024; then
+       AC_MSG_WARN([*** the TCP port range should be 1024 or greater in --with-tcpportrange])
+    fi
+    if test $max_tcp_port -ge 65536; then
+       AC_MSG_WARN([*** the TCP port range should be less than 65536 in --with-tcpportrange])
+    fi
+    AC_DEFINE_UNQUOTED(TCPPORTRANGE,$TCPPORTRANGE,[A comma-separated list of two integers, determining the minimum and
+   maximum unreserved TCP port numbers sockets should be bound to. ])
+fi
+
+AC_ARG_WITH(udpportrange,
+    [  --with-udpportrange=low,high  bind reserved UDP server sockets to ports within this range [unlimited]],
+    [
+       UDPPORTRANGE="$withval"
+    ]
+)
+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
+       AC_MSG_ERROR([*** --with-udpportrange requires two comma-separated positive numbers])
+    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
+       AC_MSG_ERROR([*** the second UDP port number must be greater than the first in --with-udpportrange])
+    fi
+    if test $max_udp_port -ge 1024; then
+       AC_MSG_WARN([*** the UDP port range should be less than 1024 in --with-udpportrange])
+    fi
+    if test $min_udp_port -le 0; then
+       AC_MSG_WARN([*** the UDP port range should be greater than 0 in --with-udpportrange])
+    fi
+    AC_DEFINE_UNQUOTED(UDPPORTRANGE,$UDPPORTRANGE,[A comma-separated list of two integers, determining the minimum and
+   maximum reserved UDP port numbers sockets should be bound to. ])
+fi
+
+AC_ARG_WITH(maxtapeblocksize,
+    [  --with-maxtapeblocksize=kb            Maximum size of a tape block],
+    [
+       MAXTAPEBLOCKSIZE="$withval"
+    ],
+    : ${MAXTAPEBLOCKSIZE=32}
+)
+
+AC_DEFINE_UNQUOTED(MAX_TAPE_BLOCK_KB,($MAXTAPEBLOCKSIZE),[Maximum size of a tape block in KBytes.])
+AC_SUBST(MAXTAPEBLOCKSIZE)
+
+AC_ARG_WITH(db,
+    [  --with-db={text,db,dbm,gdbm,ndbm} use the selected database format [text]],
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([*** You must supply an argument to the --with-db option.])
+         ;;
+       *) DB_STYLE="$withval"
+         ;;
+       esac
+    ]
+)
+if test "$DB_STYLE"; then
+    case "$DB_STYLE" in
+       db | dbm | gdbm | ndbm | text)  ;;
+       *)
+           AC_MSG_ERROR([*** Unknown argument $DB_STYLE given to --with-db.  Choose from db, dbm, gdbm, ndbm, text.])
+           DB_STYLE=
+           ;;
+    esac
+fi
+
+AC_ARG_WITH(mmap,
+    [  --with-mmap            force use of mmap instead of shared memory support],
+    FORCE_MMAP=$withval,
+    : ${FORCE_MMAP=no}
+)
+case "$FORCE_MMAP" in
+y | ye | yes | n | no) : ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-mmap.])
+  ;;
+esac
+
+AC_ARG_WITH(buffered-dump,
+    [  --with-buffered-dump   buffer the dumping sockets on the server for speed],
+    DUMPER_SOCKET_BUFFERING=$withval,
+    : ${DUMPER_SOCKET_BUFFERING=no}
+)
+case "$DUMPER_SOCKET_BUFFERING" in
+n | no) :
+  ;;
+y | ye | yes) AC_DEFINE(DUMPER_SOCKET_BUFFERING,1,[Define if dumper should buffer the sockets for faster throughput. ])
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-buffered-dump.])
+  ;;
+esac
+
+AC_ARG_WITH(assertions,
+    [  --with-assertions      compile assertions into code],
+    ASSERTIONS="$withval",
+    : ${ASSERTIONS=no}
+)
+case "$ASSERTIONS" in
+n | no) : ;;
+y |  ye | yes) AC_DEFINE(ASSERTIONS,1,[Define if you want assertion checking. ])
+  ;;
+*) AC_MSG_ERROR([*** You must not supply an argument to --with-assertions option.])
+  ;;
+esac
+
+AC_ARG_WITH(tmpdir,
+    [  --with-tmpdir[=/temp/dir] area Amanda can use for temp files [/tmp/amanda]],
+    tmpdir="$withval",
+    : ${tmpdir=yes}
+)
+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) AC_MSG_ERROR([*** --without-tmpdir is not allowed.]);;
+y |  ye | yes)
+       AMANDA_TMPDIR="/tmp/amanda";;
+/*)
+       AMANDA_TMPDIR="$tmpdir";;
+*) AC_MSG_ERROR([*** You must supply a full pathname to --with-tmpdir option.]);;
+esac
+AC_DEFINE_UNQUOTED(AMANDA_TMPDIR,"$AMANDA_TMPDIR",[The directory in which Amanda should create temporary files. ])
+AC_SUBST(AMANDA_TMPDIR)
+
+AC_ARG_WITH(debugging,
+    [  --with[out]-debugging[=/debug/dir] [do not] record runtime debugging information in specified directory [--with-tmpdir]],
+    debugging="$withval",
+    : ${debugging=yes}
+)
+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" ;;
+*) AC_MSG_ERROR([*** You must supply a full pathname to --with-debugging option.])
+  ;;
+esac
+case "$AMANDA_DBGDIR" in
+"") :;;
+*) AC_DEFINE(DEBUG_CODE,1,[Define if you want debugging. ])
+   AC_DEFINE_UNQUOTED(AMANDA_DBGDIR,"$AMANDA_DBGDIR",[Location of Amanda directories and files. ])
+   AC_SUBST(AMANDA_DBGDIR);;
+esac
+
+AC_ARG_WITH(debug_days,
+    [  --with-debug-days=NN    number of days to keep debugging files [default=4]],
+    debug_days="$withval",
+    : ${debug_days=4}
+)
+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" ;;
+*) AC_MSG_ERROR([*** --with-debug-days value not numeric or out of range.])
+  ;;
+esac
+AC_DEFINE_UNQUOTED(AMANDA_DEBUG_DAYS,$AMANDA_DEBUG_DAYS,[Number of days to keep debugging files. ])
+AC_SUBST(AMANDA_DEBUG_DAYS)
+
+AC_ARG_WITH(testing,
+    [  --with-testing[=suffix] use alternate service names],
+    TESTING="$withval",
+    : ${TESTING=no}
+)
+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"
+AC_SUBST(SERVICE_SUFFIX)
+AC_DEFINE_UNQUOTED(SERVICE_SUFFIX, "$SERVICE_SUFFIX",[A suffix that will be appended to service names.
+ * Useful for testing in parallel with a working version. ])
+AC_DEFINE_UNQUOTED(AMANDA_SERVICE_NAME,  "$AMANDA_SERVICE_NAME", [The name for the Amanda service. ])
+AC_DEFINE_UNQUOTED(KAMANDA_SERVICE_NAME, "$KAMANDA_SERVICE_NAME", [The name for the Kerberized Amanda service. ])
+
+(
+    test "x$prefix" = xNONE && prefix=$ac_default_prefix
+    test "x$exec_prefix" = xNONE && exec_prefix=${prefix}
+
+    tmp=`eval echo "$bindir"`
+    AC_DEFINE_UNQUOTED(bindir,"$tmp",[Directory in which user binaries should be installed. ])
+
+    tmp=`eval echo "$sbindir"`
+    AC_DEFINE_UNQUOTED(sbindir,"$tmp",[Directory in which administrator binaries should be installed. ])
+
+    tmp=`eval echo "$libexecdir"`
+    AC_DEFINE_UNQUOTED(libexecdir,"$tmp",[Directory in which internal binaries should be installed. ])
+
+    tmp=`eval echo $mandir`
+    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
+dnl the backup program while AIX systems can't use the dump program.  So
+dnl a variable is set up here to specify the order of dump programs to
+dnl search for on the system.
+DUMP_PROGRAMS="ufsdump dump backup"
+GETCONF_LFS="LFS"
+
+dump_returns_1=
+xenix_tapeio=
+case "$target" in
+    *-dec-osf*)
+                       AC_DEFINE(STATFS_OSF1,1,[Define on OSF1. ])
+                       ;;
+    *-dg-*)
+                       DUMP_PROGRAMS="dump "$DUMP_PROGRAMS
+                       : ${USE_RUNDUMP=yes}
+                       dump_returns_1=yes
+                       ;;
+    *-netbsd*)
+                       ;;
+    *-freebsd*)
+                       ;;
+    *-openbsd*)
+                       ;;
+    *-hp-*)
+                       MT_FILE_FLAG="-t"
+                       GETCONF_LFS="XBS5_ILP32_OFFBIG"
+                       case "$CC" in
+                           *gcc*)
+                               AMANDA_CPPFLAGS="-D__STDC_EXT__ $AMANDA_CPPFLAGS"
+                               ;;
+                           *cc*)
+                               AMANDA_CFLAGS="-Ae $AMANDA_CFLAGS"
+                               ;;
+                       esac
+                       ;;
+  *-ibm-aix*)
+                       GETCONF_LFS="XBS5_ILP32_OFFBIG"
+                       DUMP_PROGRAMS="backup "$DUMP_PROGRAMS
+                       AC_DEFINE(AIX_TAPEIO,1,[Define on AIX. ])
+                       AC_DEFINE(AIX_BACKUP,1,[Define on AIX. ])
+                       ;;
+  m88k-motorola-sysv4)
+                       ;;
+  *-nextstep3)
+                       ;;
+  *-pc-bsdi*)
+                       ;;
+  *-pc-linux-*)
+                       ;;
+  alpha*-*-linux-*)
+                       ;;
+  sparc*-*-linux-*)
+                       ;;
+  powerpc-*-linux-*)
+                       ;;
+  *-sgi-irix3*)
+                       dnl The old cc won't work!
+                       CC=gcc
+                       ;;
+  *-sgi-irix4*)
+                       ;;
+  *-sgi-irix5*)
+                       ;;
+  *-sgi-irix6*)
+                       ;;
+  *-solaris2*)
+                       ;;
+  *-sun-sunos4.1*)
+                       ;;
+  *-ultrix*)
+                       : ${USE_RUNDUMP=yes}
+                       AC_DEFINE(STATFS_ULTRIX,1,[Define on Ultrix. ])
+                       dump_returns_1=yes
+                       ;;
+  *-sysv4.2uw2*)
+                       AC_DEFINE(UWARE_TAPEIO,1,[Define on UnixWare. ])
+                       ;;
+  *-sco3.2v4*)
+                       DEV_PREFIX=/dev/
+                       RDEV_PREFIX=/dev/
+                       ;;
+  *-sco3.2v5*)
+                       xenix_tapeio=yes
+                       AC_DEFINE(STATFS_SCO_OS5,1,[Define on SCO OS5. ])
+                       ;;
+  i386-pc-isc4*)
+                       xenix_tapeio=yes
+                       ;;
+  *-sni-sysv4)
+                       ;;
+  *-pc-cygwin)
+                       AC_DEFINE(IGNORE_TAR_ERRORS,1,[Define on Cygwin. ])
+                       # Cygwin needs PATH to find cygwin1.dll
+                       AC_DEFINE(NEED_PATH_ENV,1,[Define on Cygwin. ])
+                       AC_DEFINE(IGNORE_UID_CHECK,1,[Define on Cygwin. ])
+                       AC_DEFINE(IGNORE_FSTAB,1,[Define on Cygwin. ])
+                       AC_DEFINE(DONT_SUID_ROOT,1,[Define on Cygwin. ])
+                       NEED_SETUID_CLIENT=false
+                       NEED_RUNTIME_PSEUDO_RELOC=true
+                       ;;
+  *)
+                       cat <<END
+
+*****
+This machine, target type $target, is not known
+to be fully supported by this configure script.  If the
+installation of Amanda on this system succeeds or needed
+any patches, please email amanda-hackers@amanda.org with
+the patches or an indication of the sucess or failure of
+the Amanda installation on your system.
+*****
+
+END
+               ;;
+esac
+
+if test -n "$dump_returns_1"; then
+  AC_DEFINE(DUMP_RETURNS_1,1,[Define this if this system's dump exits with 1 as a success code. ])
+fi
+
+if test -n "$xenix_tapeio"; then
+  AC_DEFINE(XENIX_TAPEIO,1,[Define on XENIX/ISC. ])
+fi
+
+AMANDA_CFLAGS="$AMANDA_CFLAGS $KRB4INCLUDES"
+AMANDA_CPPFLAGS="$AMANDA_CPPFLAGS $KRB4INCLUDES"
+AMANDA_LDFLAGS="$AMANDA_LDFLAGS $KRB4LDFLAGS"
+AMANDA_LIBS="$KRB4LIBS $AMANDA_LIBS"
+CFLAGS="$CFLAGS $AMANDA_CFLAGS"
+CPPFLAGS="$CPPFLAGS $AMANDA_CPPFLAGS"
+LDFLAGS="$LDFLAGS $AMANDA_LDFLAGS"
+LIBS="$AMANDA_LIBS $LIBS"
+
+
+dnl This specifies the flag for mt that tells mt the proper tape drive
+dnl to use.
+: ${MT_FILE_FLAG="-f"}
+AC_SUBST(MT_FILE_FLAG)
+AC_DEFINE_UNQUOTED(MT_FILE_FLAG, "$MT_FILE_FLAG",[Defined to the switch to be used when invoking mt to specify the
+ * tape device. ])
+
+AX_CREATE_STDINT_H(common-src/amanda-int.h)
+
+dnl Check for programs.
+AC_PATH_PROGS(AR,ar,,$LOCSYSPATH)
+
+AC_PROG_AWK
+AMANDA_PROG_AWK_VAR
+if test "$amanda_cv_awk_var_assignment" = no; then
+    NO_AMPLOT_MODE=true
+    AC_MSG_WARN([*** Your $awk cannot do command line variable assignment.  Amplot will not be installed.])
+fi
+
+AC_PROG_YACC
+AC_PATH_PROGS(CAT,cat,,$LOCSYSPATH)
+if test -z "$CAT"; then
+    CAT=cat
+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)
+if test -z "$GNUPLOT"; then
+    NO_AMPLOT_MODE=true
+    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
+   *GNU*tar* | *Free*paxutils* )
+               AC_DEFINE_UNQUOTED(GNUTAR,"$GNUTAR",[Define to the location of Gnu tar. ])
+               ;;
+   *)
+               AC_MSG_WARN([*** $GNUTAR is not GNU tar, so it will not be used.])
+               GNUTAR=
+               ;;
+  esac
+fi
+
+if test "x$SAMBA_CLIENT" != "xno"
+then AC_PATH_PROGS(SAMBA_CLIENT,smbclient,,$LOCSYSPATH)
+else SAMBA_CLIENT=
+fi
+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
+               ;;
+  *)
+               AC_MSG_WARN([*** $SAMBA_CLIENT does not seem to be smbclient, so it will not be used.])
+               SAMBA_CLIENT=
+               ;;
+  esac
+  if test -n "$SAMBA_CLIENT"; then
+    AC_DEFINE_UNQUOTED(SAMBA_CLIENT,"$SAMBA_CLIENT",[Define the location of smbclient for backing up Samba PC clients. ])
+    AC_DEFINE_UNQUOTED(SAMBA_VERSION, $smbversion,
+      [Not the actual samba version, just a number that should be increased whenever we start to rely on a new samba feature. ])
+  fi
+
+fi
+
+
+AC_PATH_PROGS(GZIP,gzip,,$LOCSYSPATH)
+if test "$GZIP"; then
+    AC_DEFINE(HAVE_GZIP,1,[Define if Amanda is using the gzip program. ])
+    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
+       dnl If we have to use cat, we don't define COMPRESS_FAST_OPT,
+       dnl COMPRESS_BEST_OPT, or UNCOMPRESS_OPT as "" since cat will look
+       dnl look for a file by the name of "".
+       AC_MSG_WARN([*** Cannot find either gzip or compress.  Using cat. ***])
+       COMPRESS_PATH="$CAT"
+       COMPRESS_SUFFIX=""
+       COMPRESS_FAST_OPT=""
+       COMPRESS_BEST_OPT=""
+       UNCOMPRESS_PATH="$CAT"
+       UNCOMPRESS_OPT=""
+    fi
+fi
+AC_DEFINE_UNQUOTED(COMPRESS_PATH,"$COMPRESS_PATH",[Define to the exact path to the gzip or the compress program. ])
+AC_DEFINE_UNQUOTED(COMPRESS_SUFFIX,"$COMPRESS_SUFFIX",[Define to the suffix for the COMPRESS_PATH compression program. ])
+AC_DEFINE_UNQUOTED(COMPRESS_FAST_OPT,"$COMPRESS_FAST_OPT",[Define as the command line option for fast compression. ])
+AC_DEFINE_UNQUOTED(COMPRESS_BEST_OPT,"$COMPRESS_BEST_OPT",[Define as the command line option for best compression. ])
+AC_DEFINE_UNQUOTED(UNCOMPRESS_PATH,"$UNCOMPRESS_PATH",[Define as the exact path to the gzip or compress command. ])
+AC_DEFINE_UNQUOTED(UNCOMPRESS_OPT,"$UNCOMPRESS_OPT",[Define as any optional arguments to get UNCOMPRESS_PATH to uncompress. ])
+
+AC_PATH_PROGS(MAILER,Mail mailx mail)
+if test -z "$MAILER"; then
+    if $NO_SERVER_MODE; then
+       MAILER="NONE"
+       AC_MSG_WARN([*** WARNING: Amanda cannot send mail reports without these programs.])
+    else
+       AC_MSG_ERROR([Set MAILER to some program that accepts -s subject user < message_file.])
+    fi
+fi
+AC_DEFINE_UNQUOTED(MAILER,"$MAILER",[Define to a program that understands -s "subject" user < message_file])
+
+AC_PATH_PROGS(MT,mt,mt,$LOCSYSPATH)
+
+AC_PATH_PROGS(CHIO,chio,chio,$LOCSYSPATH)
+
+AC_PATH_PROGS(CHS,chs,chs,$LOCSYSPATH)
+
+AC_PATH_PROGS(MTX,mtx,mtx,$LOCSYSPATH)
+
+AC_PATH_PROGS(MCUTIL,mcutil,mcutil,$LOCSYSPATH)
+
+AC_PATH_PROGS(PRINT, lpr lp)
+if test ! -z "$PRINT"; then
+    AC_DEFINE_UNQUOTED(LPRCMD, "$PRINT",[Command for starting printing jobs. ])
+    AC_CACHE_CHECK([which flag to use to select a printer],
+       amanda_cv_printer_flag, [
+       amanda_cv_printer_flag=$PRINTER_FLAG
+       case "$PRINT" in
+       lpr|*/lpr) amanda_cv_printer_flag="-P";;
+       lp|*/lp) amanda_cv_printer_flag="-d";;
+       esac
+    ])
+    if test ! -z "$amanda_cv_printer_flag"; then
+       AC_DEFINE_UNQUOTED(LPRFLAG, "$amanda_cv_printer_flag",[LPRCMD switch for specifying a printer name. ])
+    else
+       AC_MSG_WARN([*** WARNING: amanda will always print to the default printer])
+    fi
+fi
+
+AC_PATH_PROGS(PCAT,pcat,,$LOCSYSPATH)
+AC_PATH_PROGS(PERL,perl5 perl,,$LOCSYSPATH)
+
+dnl AC_PATH_PROGS(MAKEINFO,makeinfo,,$LOCSYSPATH)
+dnl AC_PATH_PROGS(TEXI2DVI,texi2dvi,,$LOCSYSPATH)
+
+AC_PATH_PROGS(DUMP,$DUMP_PROGRAMS,,$SYSLOCPATH)
+AC_PATH_PROGS(RESTORE,ufsrestore restore,,$SYSLOCPATH)
+if test "$DUMP" -a "$RESTORE"; then
+    AC_DEFINE_UNQUOTED(DUMP,"$DUMP",[Define the location of the ufsdump, backup, or dump program. ])
+    AC_DEFINE_UNQUOTED(RESTORE,"$RESTORE",[Define the location of the ufsrestore or restore program. ])
+    if test -x $DUMP; then
+        AC_CACHE_CHECK(
+           [whether $DUMP supports -E or -S for estimates],
+           amanda_cv_dump_estimate,
+           [
+               case "$DUMP" in
+               *dump)
+                   AC_TRY_COMMAND($DUMP 9Ef /dev/null /dev/null/invalid/fs 2>&1
+                       | $GREP -v Dumping
+                       | $GREP -v Date
+                       | $GREP -v Label >conftest.d-E 2>&1)
+                   cat conftest.d-E >&AS_MESSAGE_LOG_FD()
+                   AC_TRY_COMMAND($DUMP 9Sf /dev/null /dev/null/invalid/fs 2>&1
+                       | $GREP -v Dumping
+                       | $GREP -v Date
+                       | $GREP -v Label >conftest.d-S 2>&1)
+                   cat conftest.d-S >&AS_MESSAGE_LOG_FD()
+                   AC_TRY_COMMAND($DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
+                       | $GREP -v Dumping
+                       | $GREP -v Date
+                       | $GREP -v Label >conftest.d 2>&1)
+                   cat conftest.d >&AS_MESSAGE_LOG_FD()
+                   if AC_TRY_COMMAND(cmp conftest.d-E conftest.d 1>&2); then
+                       amanda_cv_dump_estimate=E
+                   elif AC_TRY_COMMAND(cmp conftest.d-S conftest.d 1>&2); 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
+           ])
+    else
+       AC_MSG_WARN([*** $DUMP is not executable, cannot run -E/-S test])
+       amanda_cv_dump_estimate=no
+    fi
+    if test "$amanda_cv_dump_estimate" != no; then
+       AC_DEFINE_UNQUOTED(HAVE_DUMP_ESTIMATE, "$amanda_cv_dump_estimate",[Define to the string that enables dump estimates. ])
+    fi
+
+    AC_ARG_WITH(dump-honor-nodump,
+    [  --with-dump-honor-nodump  if dump supports -h, use it for level0s too],
+    [ if test -x $DUMP; then
+        AC_CACHE_CHECK(
+         [whether $DUMP supports -h (honor nodump flag)],
+         amanda_cv_honor_nodump,
+         [
+           case "$DUMP" in
+           *dump)
+               AC_TRY_COMMAND($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)
+               cat conftest.d-h >&AS_MESSAGE_LOG_FD()
+               AC_TRY_COMMAND($DUMP 9f /dev/null /dev/null/invalid/fs 2>&1
+                   | $GREP -v Dumping
+                   | $GREP -v Date
+                   | $GREP -v Label >conftest.d 2>&1)
+               cat conftest.d >&AS_MESSAGE_LOG_FD()
+               if AC_TRY_COMMAND(diff conftest.d-h conftest.d 1>&2); 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
+         ])
+      else
+       AC_MSG_WARN([*** $DUMP is not executable, cannot run -h test])
+       amanda_cv_honor_nodump=no
+      fi
+      if test "$amanda_cv_honor_nodump" = yes; then
+       AC_DEFINE(HAVE_HONOR_NODUMP,1,[Define this if dump accepts -h for honoring nodump. ])
+      fi
+    ])
+fi
+
+AC_PATH_PROGS(XFSDUMP,xfsdump,,$SYSLOCPATH)
+AC_PATH_PROGS(XFSRESTORE,xfsrestore,,$SYSLOCPATH)
+if test "$XFSDUMP" -a "$XFSRESTORE"; then
+    AC_DEFINE_UNQUOTED(XFSDUMP,"$XFSDUMP",[Define the location of the xfsdump program on Irix hosts. ])
+    AC_DEFINE_UNQUOTED(XFSRESTORE,"$XFSRESTORE",[Define the location of the xfsrestore program on Irix hosts. ])
+    AC_MSG_WARN([*** xfsdump causes the setuid-root rundump program to be enabled])
+    AC_MSG_WARN([[*** to disable it, just #undef XFSDUMP in config/config.h]])
+fi
+
+VXSYSLOCPATH="$SYSLOCPATH:/usr/lib/fs/vxfs"
+AC_PATH_PROGS(VXDUMP,vxdump,,$VXSYSLOCPATH)
+AC_PATH_PROGS(VXRESTORE,vxrestore,,$VXSYSLOCPATH)
+if test "$VXDUMP" -a "$VXRESTORE"; then
+    AC_DEFINE_UNQUOTED(VXDUMP,"$VXDUMP",[Define the location of the vxdump program on HPUX and SINIX hosts or on
+ * other hosts where the Veritas filesystem (vxfs) has been installed. ])
+    AC_DEFINE_UNQUOTED(VXRESTORE,"$VXRESTORE",[Define the location of the vxrestore program on HPUX and SINIX hosts or on
+ * other hosts where the Veritas filesystem (vxfs) has been installed. ])
+fi
+
+AC_PATH_PROGS(VDUMP,vdump,,$SYSLOCPATH)
+AC_PATH_PROGS(VRESTORE,vrestore,,$SYSLOCPATH)
+if test "$VDUMP" -a "$VRESTORE"; then
+    AC_DEFINE_UNQUOTED(VDUMP,"$VDUMP",[Define the location of the vdump program. ])
+    AC_DEFINE_UNQUOTED(VRESTORE,"$VRESTORE",[Define the location of the vrestore program. ])
+fi
+
+dnl Handle all of the substitutions to make amplot work.
+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"
+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
+AC_SUBST(AMPLOT_COMPRESS)
+AC_SUBST(AMPLOT_CAT_GZIP)
+AC_SUBST(AMPLOT_CAT_COMPRESS)
+AC_SUBST(AMPLOT_CAT_PACK)
+
+dnl Empty GZIP so that make dist works.
+GZIP=
+
+dnl Checks for compilers, typedefs, structures, and compiler characteristics.
+dnl Check for large file compilation environment.
+need_resetofs=yes
+AC_CACHE_CHECK(
+    [for large file compilation CFLAGS],
+    amanda_cv_LFS_CFLAGS,
+    [
+       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
+    ]
+)
+AC_CACHE_CHECK(
+    [for large file compilation LDFLAGS],
+    amanda_cv_LFS_LDFLAGS,
+    [
+       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_CACHE_CHECK(
+    [for large file compilation LIBS],
+    amanda_cv_LFS_LIBS,
+    [
+       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
+    ]
+)
+if test "$need_resetofs" = yes; 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"
+LDFLAGS="$amanda_cv_LFS_LDFLAGS $LDFLAGS"
+LIBS="$amanda_cv_LFS_LIBS $LIBS"
+
+AM_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+AC_PROG_GCC_TRADITIONAL
+AC_C_CONST
+AMANDA_C_VOLATILE
+AMANDA_C_UNSIGNED_LONG_CONSTANTS
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+
+dnl We don't have an acconfig.h template since we moved all define templates
+dnl into the third argument of AC_DEFINE.  However, AC_CHECK_TYPE calls
+dnl AC_DEFINE without such an argument, so autoheader complains about no
+dnl template being available.  This is an ugly work-around.
+
+pushdef([AC_DEFINE_SAVED],defn([AC_DEFINE]))
+pushdef([AC_DEFINE],[AC_DEFINE_SAVED([$1],[$2],[Define to $2 if $1 is not defined])])
+
+AC_CHECK_TYPE(ssize_t, int)
+
+dnl there is a push to avoid depending on long longs, so in general it's
+dnl better to convert numbers to kilobytes for consistancies sake.  This
+dnl is primarily checked for for client-src/amqde.c
+AC_CHECK_TYPES(unsigned long long)
+
+popdef([AC_DEFINE])
+popdef([AC_DEFINE_SAVED])
+
+dnl End ugly AC_CHECK_TYPE work-around.
+
+AC_TYPE_UID_T
+AC_TYPE_SIGNAL
+AC_STRUCT_TM
+AM_PROG_LEX
+
+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],
+[AC_REQUIRE([AC_HEADER_STDC])dnl
+AC_MSG_CHECKING(for $1)
+AC_CACHE_VAL(ac_cv_type_$1,
+[AC_EGREP_CPP(dnl
+changequote(<<,>>)dnl
+<<(^|[^a-zA-Z_0-9])$1[^a-zA-Z_0-9]>>dnl
+changequote([,]), [#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+#include <$3>], ac_cv_type_$1=yes, ac_cv_type_$1=no)])dnl
+AC_MSG_RESULT($ac_cv_type_$1)
+if test $ac_cv_type_$1 = no; then
+  AC_DEFINE($1, $2, [Define if $1 is not a standard system type])
+fi
+])
+AMANDA_CHECK_TYPE(socklen_t, int, sys/socket.h)
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+CF_WAIT
+AC_HEADER_TIME
+AC_CHECK_HEADERS(\
+       arpa/inet.h \
+       camlib.h \
+       cam/cam.h \
+       cam/scsi/scsi_message.h \
+       chio.h \
+       db.h \
+       dbm.h \
+       fcntl.h \
+       fnmatch.h \
+       fstab.h \
+       grp.h \
+       history.h \
+       libc.h \
+       limits.h \
+       linux/zftape.h \
+       mntent.h \
+       mnttab.h \
+       ndbm.h \
+       netdb.h \
+       netinet/in_systm.h \
+       readline.h \
+       readline/history.h \
+       readline/readline.h \
+       scsi/sg.h \
+       scsi/scsi_ioctl.h \
+       stdlib.h \
+       string.h \
+       strings.h \
+       sys/chio.h \
+       sys/dsreq.h \
+       sys/fcntl.h \
+       sys/file.h \
+       sys/ioctl.h \
+       sys/ipc.h \
+       sys/mman.h \
+       sys/mntent.h \
+       sys/mtio.h \
+       sys/param.h \
+       sys/scarray.h \
+       sys/gscdds.h \
+       sys/scsiio.h \
+       sys/scsi.h \
+       sys/scsi/impl/uscsi.h \
+       sys/scsi/scsi/ioctl.h \
+       sys/select.h \
+       sys/shm.h \
+       sys/stat.h \
+       sys/statfs.h \
+       sys/statvfs.h \
+       sys/tape.h \
+       sys/time.h \
+       sys/types.h \
+       sys/vfs.h \
+       sys/vfstab.h \
+       syslog.h \
+       unistd.h \
+       vtblc.h \
+)
+
+AC_CHECK_HEADERS(netinet/ip.h,,,
+[[#include <sys/socket.h>
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#include <netinet/in.h>
+]])
+
+AC_CHECK_HEADERS(sys/mount.h,,,
+[[#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+]])
+
+NO_SCSI_CHANGER_MODE=true
+NO_CHIO_CHANGER_MODE=true
+
+AC_C_BIGENDIAN
+
+dnl
+dnl chio support
+dnl
+if test x"$ac_cv_header_sys_scsi_h" = x"yes"; then
+    AC_CACHE_CHECK([for HP/UX-like scsi changer support],
+       amanda_cv_hpux_scsi_chio,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/scsi.h>
+]], [[
+       static struct element_addresses changer_info;
+       int i = SIOC_ELEMENT_ADDRESSES;
+       int j = SIOC_ELEMENT_STATUS;
+       int k = SIOC_MOVE_MEDIUM;
+]])],[amanda_cv_hpux_scsi_chio=yes],[amanda_cv_hpux_scsi_chio=no])])
+    if test x"$amanda_cv_hpux_scsi_chio" = x"yes"; then
+       AC_DEFINE(HAVE_HPUX_SCSI_CHIO,1,[Define to enable HPUX chio based changer support. ])
+       NO_SCSI_CHANGER_MODE=false
+    fi
+fi
+
+dnl
+dnl Linux SCSI based on ioctl
+dnl
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_scsi_scsi_ioctl_h" = x"yes"; then 
+       AC_CACHE_CHECK([for Linux like scsi support (ioctl)],
+       amanda_cv_linux_scsi,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <scsi/scsi_ioctl.h>
+#include <sys/mtio.h>
+]], [[
+       int device;
+       char *Command;
+       ioctl(device, SCSI_IOCTL_SEND_COMMAND, Command);
+]])],[amanda_cv_linux_scsi=yes],[amanda_cv_linux_scsi=no])])
+fi
+
+dnl
+dnl Linux SCSI based on sg
+dnl
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_scsi_sg_h" = x"yes"; then 
+       AC_CACHE_CHECK([for Linux like scsi support (sg)],
+       amanda_cv_linux_sg_scsi,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <scsi/sg.h>
+#include <sys/mtio.h>
+]], [[
+       int device;
+       struct sg_header *psg_header;
+       char *buffer;
+       write(device, buffer, 1);
+]])],[amanda_cv_linux_sg_scsi=yes],[amanda_cv_linux_sg_scsi=no])])
+fi
+
+if test x"$amanda_cv_linux_scsi" = x"yes" ||
+ test x"$amanda_cv_linux_sg_scsi" = x"yes";then
+       AC_DEFINE(HAVE_LINUX_LIKE_SCSI,1,[Define to enable Linux tape-changer support.])
+       NO_SCSI_CHANGER_MODE=false
+fi
+
+dnl
+dnl HP-UX SCSI
+dnl
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scsi_h" = x"yes"; then 
+       AC_CACHE_CHECK([for HP-UX like scsi support],
+       amanda_cv_hpux_scsi,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/scsi.h>
+#include <sys/mtio.h>
+]], [[
+       int device;
+       char *Command;
+       ioctl(device, SIOC_IO, Command);
+]])],[amanda_cv_hpux_scsi=yes],[amanda_cv_hpux_scsi=no])])
+       if test x"$amanda_cv_hpux_scsi" = x"yes";then
+               AC_DEFINE(HAVE_HPUX_LIKE_SCSI,1,[Define to enable HPUX tape-changer support. ])
+               NO_SCSI_CHANGER_MODE=false
+               NO_CHIO_CHANGER_MODE=false
+       fi
+fi
+
+dnl
+dnl IRIX SCSI
+dnl
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_dsreq_h" = x"yes"; then 
+       AC_CACHE_CHECK([for Irix like scsi support],
+       amanda_cv_irix_scsi,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/dsreq.h>
+#include <sys/mtio.h>
+]], [[
+       int device=1;
+       char Command;
+       ioctl(device, DS_ENTER, &Command);
+]])],[amanda_cv_irix_scsi=yes],[amanda_cv_irix_scsi=no])])
+       if test x"$amanda_cv_irix_scsi" = x"yes";then
+               AC_DEFINE(HAVE_IRIX_LIKE_SCSI,1,[Define to enable IRIX tape-changer support])
+               NO_SCSI_CHANGER_MODE=false
+       fi
+fi
+
+dnl
+dnl Solaris  SCSI
+dnl
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scsi_impl_uscsi_h" = x"yes"; then 
+       AC_CACHE_CHECK([for Solaris like scsi support],
+       amanda_cv_solaris_scsi,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/scsi/impl/uscsi.h>
+#include <sys/mtio.h>
+]], [[
+       int device;
+       char *Command;
+       ioctl(device, USCSICMD, Command);
+]])],[amanda_cv_solaris_scsi=yes],[amanda_cv_solaris_scsi=no])])
+       if test x"$amanda_cv_solaris_scsi" = x"yes";then
+               AC_DEFINE(HAVE_SOLARIS_LIKE_SCSI,1,[Define to enable Solaris tape-changer support])
+               NO_SCSI_CHANGER_MODE=false
+       fi
+fi
+
+dnl
+dnl AIX SCSI
+dnl
+if test x"$ac_cv_header_sys_tape_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scarray_h" = x"yes" &&
+   test x"$ac_cv_header_sys_gscdds_h" = x"yes"; then 
+       AC_CACHE_CHECK([for AIX like scsi support],
+       amanda_cv_aix_scsi,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/scarray.h>
+#include <sys/tape.h>
+]], [[
+       int device;
+       char *Command;
+       ioctl(device, STIOCMD, Command);
+]])],[amanda_cv_aix_scsi=yes],[amanda_cv_aix_scsi=no])])
+       if test x"$amanda_cv_aix_scsi" = x"yes";then
+               AC_DEFINE(HAVE_AIX_LIKE_SCSI,1,[Define to enable AIX tape-changer support])
+               NO_SCSI_CHANGER_MODE=false
+       fi
+fi
+dnl
+dnl BSD CAM SCSI
+dnl
+if test x"$ac_cv_header_cam_cam_h" = x"yes";then
+       AC_CACHE_CHECK([for CAM like scsi support],
+       amanda_cv_cam_scsi,
+       [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+# include <fcntl.h>
+# include <cam/cam.h>
+# include <cam/cam_ccb.h>
+# include <cam/scsi/scsi_message.h>
+# include <cam/scsi/scsi_pass.h>
+# include <camlib.h>
+]], [[
+       struct cam_device *curdev;
+
+       curdev = cam_open_pass("", O_RDWR, NULL);
+]])],[amanda_cv_cam_scsi=yes],[amanda_cv_cam_scsi=no])])
+       if test x"$amanda_cv_cam_scsi" = x"yes";then
+               AC_DEFINE(HAVE_CAM_LIKE_SCSI,1,[Define to enable CAM tape-changer support])
+               NO_SCSI_CHANGER_MODE=false
+               AC_CHECK_LIB(cam,main)
+       fi
+fi
+
+dnl
+dnl BSD SCSI
+dnl
+if test x"$ac_cv_header_sys_mtio_h" = x"yes" &&
+   test x"$ac_cv_header_sys_scsiio_h" = x"yes"; then
+    AC_CACHE_CHECK([for BSD like scsi support],
+    amanda_cv_bsd_scsi,
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/scsiio.h>
+#include <sys/mtio.h>
+]], [[
+    int device=1;
+    char Command;
+    ioctl(device, SCIOCCOMMAND, &Command);
+]])],[amanda_cv_bsd_scsi=yes],[amanda_cv_bsd_scsi=no])])
+    if test x"$amanda_cv_bsd_scsi" = x"yes";then
+       AC_DEFINE(HAVE_BSD_LIKE_SCSI,1,[Define to enable BSD tape-changer support])
+       NO_SCSI_CHANGER_MODE=false
+    fi
+fi
+
+dnl Do not build chg-scsi-chio if we cannot find the needed support
+dnl include files for the SCSI interfaces
+dnl chio.h and sys/chio.h are chio based systems
+if test x"$ac_cv_header_chio_h" = x"yes" ||
+   test x"$ac_cv_header_sys_chio_h" = x"yes"; then
+   dnl chg-scsi does not support FreeBSD 3.0's chio.h; it became backward
+   dnl incompatible with the introduction of camlib.h
+   if test x"$ac_cv_header_camlib_h" != x"yes"; then
+     if $NO_SCSI_CHANGER_MODE; then
+       NO_SCSI_CHANGER_MODE=false
+     else
+       NO_CHIO_CHANGER_MODE=false
+     fi
+   fi
+fi
+
+dnl cur_colr is on some HP's
+AC_CHECK_LIB(cur_colr,main)
+
+AC_CHECK_LIB(intl,main)
+
+dnl Make sure we don't use -lnsl and -lsun on Irix systems.
+case "$target" in
+    *sgi-irix*)
+                       AC_CHECK_LIB(socket,main)
+                       ;;
+    *)
+                       AC_CHECK_LIB(nsl,main)
+                       AC_CHECK_LIB(socket,main)
+                       AC_CHECK_LIB(sun,main)
+                       ;;
+esac
+
+AC_CHECK_LIB(termcap,tgetent)
+if test "$ac_cv_lib_termcap_tgetent" != yes; then
+    AC_CHECK_LIB(curses,tgetent)
+    if test "$ac_cv_lib_curses_tgetent" != yes; then
+       AC_CHECK_LIB(ncurses,tgetent)
+    fi
+fi
+if test "$ac_cv_lib_termcap_tgetent" = yes ||
+   test "$ac_cv_lib_curses_tgetent" = yes ||
+   test "$ac_cv_lib_ncurses_tgetent" = yes; then
+    AC_CHECK_LIB(readline,readline)
+    if test "$ac_cv_lib_readline_readline" != yes; then
+       AC_MSG_WARN([*** No readline library, no history and command line editing in amrecover!])
+    fi
+else
+    AC_MSG_WARN([*** No terminal library, no history and command line editing in amrecover!])
+fi
+
+if test "$ac_cv_lib_readline_readline" = yes; then
+    READLINE_LIBS=-lreadline
+    LIBS=`echo $LIBS | sed s/-lreadline//`
+    AC_SUBST(READLINE_LIBS)
+fi
+
+if test "$ac_cv_header_linux_zftape_h" = yes; then
+    if test "$ac_cv_header_vtblc_h" = yes; then
+        AC_CHECK_LIB(vtblc,main)
+        if test "$ac_cv_lib_vtblc_main" != yes; then
+            AC_MSG_WARN([*** vtblc library not found - no QIC volume table support!])
+        fi
+    else
+        AC_MSG_WARN([*** vtblc headers not found - no QIC volume table support!])
+    fi
+fi
+
+AC_CHECK_LIB(m,modf)
+
+dnl Check for various "mt status" related structure elements.
+
+AC_MSG_CHECKING(for mt_flags mtget structure element)
+mt_flags_result="found"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+]], [[
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_flags;
+]])],[AC_DEFINE(HAVE_MT_FLAGS,1,Define if the mtget structure has an mt_flags field)],[mt_flags_result="not found"])
+AC_MSG_RESULT($mt_flags_result)
+
+AC_MSG_CHECKING(for mt_fileno mtget structure element)
+mt_fileno_result="found"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+]], [[
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_fileno;
+]])],[AC_DEFINE(HAVE_MT_FILENO,1,Define if the mtget structure has an mt_fileno field)],[mt_fileno_result="not found"])
+AC_MSG_RESULT($mt_fileno_result)
+
+AC_MSG_CHECKING(for mt_blkno mtget structure element)
+mt_blkno_result="found"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+]], [[
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_blkno;
+]])],[AC_DEFINE(HAVE_MT_BLKNO,1,Define if the mtget structure has an mt_blkno field)],[mt_blkno_result="not found"])
+AC_MSG_RESULT($mt_blkno_result)
+
+AC_MSG_CHECKING(for mt_dsreg mtget structure element)
+mt_dsreg_result="found"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+]], [[
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_dsreg;
+]])],[AC_DEFINE(HAVE_MT_DSREG,1,Define if the mtget structure has an mt_dsreg field)],[mt_dsreg_result="not found"])
+AC_MSG_RESULT($mt_dsreg_result)
+
+AC_MSG_CHECKING(for mt_erreg mtget structure element)
+mt_erreg_result="found"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mtio.h>
+]], [[
+    struct mtget buf;
+    long ds;
+
+    ds = buf.mt_erreg;
+]])],[AC_DEFINE(HAVE_MT_ERREG,1,Define if the mtget structure has an mt_erreg field)],[mt_erreg_result="not found"])
+AC_MSG_RESULT($mt_erreg_result)
+
+dnl
+
+dnl Check if the system does support the user requested database library.
+dnl Begin by checking for the header file.  If it is not there, then do
+dnl not use the library.  If the header file is there, then try to link
+dnl against the library.   If it's not there, then try to link using
+dnl just the -lc library.  If the link against -lc fails, then do not
+dnl use this library.
+DB_HEADER=
+DB_LIB=
+
+dnl Testing if libc contains the dbm_open routine is tested for a
+dnl lot of times below.  We do it once here now.
+save_LIBS="$LIBS"
+AC_CHECK_LIB(c,dbm_open)
+LIBS="$save_LIBS"
+
+case "$DB_STYLE" in
+    db)
+       if test "$ac_cv_header_db_h" = yes; then
+           AC_CHECK_LIB(db,main)
+           if test "$ac_cv_lib_db_main" = yes; then
+               AC_CHECK_LIB(db,dbm_open)
+               if test "$ac_cv_lib_db_dbm_open" = yes; then
+                   DB_HEADER=db.h
+                   DB_LIB=db
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** db database library requested but dbm_open not found in -ldb.])
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=db.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** db library requested but -ldb doesn't exist and dbm_open cannot be found.])
+               fi
+           fi
+       else
+           DB_STYLE=
+           AC_MSG_WARN([*** db database library requested but db.h not found.])
+       fi
+       ;;
+
+    dbm)
+       if test "$ac_cv_header_dbm_h" = yes; then
+           AC_CHECK_LIB(dbm,main)
+           if test "$ac_cv_lib_dbm_main" = yes; then
+               AC_CHECK_LIB(dbm,dbm_open)
+               if test "$ac_cv_lib_dbm_dbm_open" = yes; then
+                   DB_HEADER=dbm.h
+                   DB_LIB=dbm
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** dbm database library requested but dbm_open not found in -ldbm.])
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=dbm.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** dbm library requested but -ldbm doesn't exist and dbm_open cannot be found.])
+               fi
+           fi
+       else
+           DB_STYLE=
+           AC_MSG_WARN([*** dbm database library requested but dbm.h not found.])
+       fi
+       ;;
+
+    gdbm)
+       if test "$ac_cv_header_ndbm_h" = yes; then
+           AC_CHECK_LIB(gdbm,main)
+           if test "$ac_cv_lib_gdbm_main" = yes; then
+               AC_CHECK_LIB(gdbm,dbm_open)
+               if test "$ac_cv_lib_gdbm_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=gdbm
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** gdbm database library requested but -lgdbm not found.])
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** gdbm library requested but -lgdbm doesn't exist and dbm_open cannot be found.])
+               fi
+           fi
+       else
+           DB_STYLE=
+           AC_MSG_WARN([*** gdbm database library requested but ndbm.h not found.])
+       fi
+       ;;
+
+    ndbm)
+       if test "$ac_cv_header_ndbm_h" = yes; then
+           AC_CHECK_LIB(ndbm,main)
+           if test "$ac_cv_lib_ndbm_main" = yes; then
+               AC_CHECK_LIB(ndbm,dbm_open)
+               if test "$ac_cv_lib_ndbm_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=ndbm
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** ndbm database library requested but -lndbm not found.])
+               fi
+           else
+               if test "$ac_cv_lib_c_dbm_open" = yes; then
+                   DB_HEADER=ndbm.h
+                   DB_LIB=c
+               else
+                   DB_STYLE=
+                   AC_MSG_WARN([*** ndbm library requested but -lndbm doesn't exist and dbm_open cannot be found.])
+               fi
+           fi
+       else
+           DB_STYLE=
+           AC_MSG_WARN([*** ndbm database library requested but ndbm.h not found.])
+       fi
+       ;;
+    text)
+       DB_HEADER=
+       DB_LIB=
+       ;;
+esac
+
+dnl If a database style was not specified select an appropriate one
+dnl automatically.
+dnl Nowadays we default to our own internal text database, but I have left
+dnl the code that does the testing here just in case it is needed one day.
+
+if test -z "$DB_STYLE"; then
+    DB_STYLE=text
+    DB_HEADER=
+    DB_LIB=
+fi
+
+dnl if test -z "$DB_STYLE" -a "$ac_cv_header_ndbm_h" = yes; then
+dnl     AC_CHECK_LIB(ndbm,dbm_open)
+dnl     if test "$ac_cv_lib_ndbm_dbm_open" = yes; then
+dnl    DB_STYLE=ndbm
+dnl    DB_HEADER=ndbm.h
+dnl    DB_LIB=ndbm
+dnl     elif test "$ac_cv_lib_c_dbm_open" = yes; then
+dnl    DB_STYLE=ndbm
+dnl    DB_HEADER=ndbm.h
+dnl    DB_LIB=c
+dnl    fi
+dnl fi
+dnl
+dnl if test -z "$DB_STYLE" -a "$ac_cv_header_db_h" = yes; then
+dnl    AC_CHECK_LIB(db,dbm_open)
+dnl    if test "$ac_cv_lib_db_dbm_open" = yes; then
+dnl    DB_STYLE=db
+dnl    DB_HEADER=db.h
+dnl    DB_LIB=db
+dnl    elif test "$ac_cv_lib_c_dbm_open" = yes; then
+dnl    DB_STYLE=db
+dnl    DB_HEADER=db.h
+dnl    DB_LIB=c
+dnl    fi
+dnl fi
+dnl
+dnl if test -z "$DB_STYLE" -a "$ac_cv_header_dbm_h" = yes; then
+dnl    AC_CHECK_LIB(dbm,dbm_open)
+dnl    if test "$ac_cv_lib_db_dbm_open" = yes; then
+dnl    DB_STYLE=dbm
+dnl    DB_HEADER=dbm.h
+dnl    DB_LIB=dbm
+dnl    elif test "$ac_cv_lib_c_dbm_open" = yes; then
+dnl    DB_STYLE=dbm
+dnl    DB_HEADER=dbm.h
+dnl    DB_LIB=c
+dnl    fi
+dnl fi
+dnl
+dnl if test -z "$DB_STYLE" -a "$ac_cv_header_ndbm_h" = yes; then
+dnl    AC_CHECK_LIB(gdbm,dbm_open)
+dnl    if test "$ac_cv_lib_gdbm_dbm_open" = yes; then
+dnl    DB_STYLE=gdbm
+dnl    DB_HEADER=ndbm.h
+dnl    DB_LIB=gdbm
+dnl    elif test "$ac_cv_lib_c_dbm_open" = yes; then
+dnl    DB_STYLE=gdbm
+dnl    DB_HEADER=ndbm.h
+dnl    DB_LIB=c
+dnl    fi
+dnl fi
+dnl
+dnl if test -z "$DB_STYLE"; then
+dnl    if test "$ac_cv_lib_c_dbm_open" = yes; then
+dnl    AC_MSG_WARN([*** A dbm_open() routine was found in -lc, but no header])
+dnl    AC_MSG_WARN([*** files exist.  Please remedy the situation.])
+dnl    else
+dnl    AC_MSG_WARN([*** No dbm_open() routine found!])
+dnl    fi
+dnl    AC_MSG_WARN([*** You may want to install the gdbm library from])
+dnl    AC_MSG_WARN([*** ftp://prep.ai.mit.edu/pub/gnu/gdbm-1.7.3.tar.gz.])
+dnl
+dnl    AC_MSG_WARN([*** Using the built-in text database.])
+dnl    DB_STYLE=text
+dnl    DB_HEADER=
+dnl    DB_LIB=
+dnl fi
+
+if test "$DB_STYLE" = text; then
+    AC_DEFINE(TEXTDB,1,[Define to enable the text-based database format. ])
+else
+    AC_MSG_CHECKING([for database])
+    AC_MSG_RESULT([header is $DB_HEADER, linking against -l$DB_LIB])
+    case "$DB_STYLE" in
+       db)     AC_DEFINE(USE_DB_H,1,[Define to enable db databases. ])   ;;
+       dbm)    AC_DEFINE(USE_DBM_H,1,[Define to enable dbm databases. ])  ;;
+       gdbm)   AC_DEFINE(USE_GDBM_H,1,[Define to enable gdbm databases. ]) ;;
+       ndbm)   AC_DEFINE(USE_NDBM_H,1,[Define to enable ndbm databases. ]) ;;
+    esac
+
+    AC_CACHE_CHECK(
+       [for struct datum declared in header files],
+       amanda_cv_struct_datum,
+       [
+           AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if defined(USE_DB_H)
+#  include <db.h>
+#else
+#  if defined(USE_DBM_H)
+#    include <dbm.h>
+#  else
+#    if defined(USE_NDBM_H)
+#      include <ndbm.h>
+#    endif
+#  endif
+#endif
+               ]], [[
+                   datum a;
+               ]])],[amanda_cv_struct_datum=yes],[amanda_cv_struct_datum=no
+           ])
+       ])
+    if test "$amanda_cv_struct_datum" = yes; then
+       AC_DEFINE(HAVE_STRUCT_DATUM,1,[Define if the database header declares struct datum. ])
+    fi
+fi
+
+case "$DB_STYLE" in
+    db) DB_EXT=.db;;
+    gdbm) DB_EXT='""';;
+    dbm | ndbm) DB_EXT=".dir .pag";;
+    text) DB_EXT='""';;
+    *) DB_EXT=;;
+esac
+AC_SUBST(DB_EXT)
+
+AC_CACHE_CHECK(whether _POSIX2_RE_DUP_MAX is defined,
+    amanda_cv_have__posix2_re_dup_max,
+    AC_EGREP_CPP(yes, [
+#include <limits.h>
+#ifdef _POSIX2_RE_DUP_MAX
+  yes
+#endif
+], amanda_cv_have__posix2_re_dup_max=yes, amanda_cv_have__posix2_re_dup_max=no))
+if test "$amanda_cv_have__posix2_re_dup_max" = yes; then
+    AC_DEFINE(HAVE__POSIX2_RE_DUP_MAX,1,[Define if limits.h defines _POSIX2_RE_DUP_MAX. ])
+fi
+
+AC_CACHE_CHECK(whether CHAR_MIN is defined,
+    amanda_cv_have_char_min,
+    AC_EGREP_CPP(yes, [
+#include <limits.h>
+#ifdef CHAR_MIN
+  yes
+#endif
+], amanda_cv_have_char_min=yes, amanda_cv_have_char_min=no))
+if test "$amanda_cv_have_char_min" = yes; then
+    AC_DEFINE(HAVE_CHAR_MIN,1,[Define if limits.h defines CHAR_MIN. ])
+fi
+
+AC_CACHE_CHECK(whether CHAR_MAX is defined,
+    amanda_cv_have_char_max,
+    AC_EGREP_CPP(yes, [
+#include <limits.h>
+#ifdef CHAR_MAX
+  yes
+#endif
+], amanda_cv_have_char_max=yes, amanda_cv_have_char_max=no))
+if test "$amanda_cv_have_char_max" = yes; then
+    AC_DEFINE(HAVE_CHAR_MAX,1,[Define if limits.h defines CHAR_MAX. ])
+fi
+
+AC_CACHE_CHECK(whether CHAR_BIT is defined,
+    amanda_cv_have_char_bit,
+    AC_EGREP_CPP(yes, [
+#include <limits.h>
+#ifdef CHAR_BIT
+  yes
+#endif
+], amanda_cv_have_char_bit=yes, amanda_cv_have_char_bit=no))
+if test "$amanda_cv_have_char_bit" = yes; then
+    AC_DEFINE(HAVE_CHAR_BIT,1,[Define if limits.h defines CHAR_BIT. ])
+fi
+
+dnl Checks for library functions and if the function is declared in
+dnl an appropriate header file.  Add some of the missing functions
+dnl to LIBOBJS.
+ICE_CHECK_DECL(accept,sys/types.h sys/socket.h)
+AC_FUNC_ALLOCA
+AC_CHECK_FUNCS(atexit)
+ICE_CHECK_DECL(atof,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)
+ICE_CHECK_DECL(bzero,string.h strings.h stdlib.h)
+AC_FUNC_CLOSEDIR_VOID
+ICE_CHECK_DECL(closelog,syslog.h)
+ICE_CHECK_DECL(connect,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(dbm_open,${DB_HEADER-no/db/header/file})
+AC_CHECK_FUNCS(endmntent)
+ICE_CHECK_DECL(fclose,stdio.h)
+ICE_CHECK_DECL(fflush,stdio.h)
+ICE_CHECK_DECL(flock,sys/file.h)
+ICE_CHECK_DECL(fprintf,stdio.h)
+ICE_CHECK_DECL(fputc,stdio.h)
+ICE_CHECK_DECL(fputs,stdio.h)
+ICE_CHECK_DECL(fread,stdio.h stdlib.h)
+ICE_CHECK_DECL(fseek,stdio.h)
+ICE_CHECK_DECL(fwrite,stdio.h stdlib.h)
+AC_REPLACE_FUNCS(getcwd)
+AC_CHECK_FUNCS(getfsent)
+ICE_CHECK_DECL(gethostname,unistd.h)
+AC_FUNC_GETMNTENT
+ICE_CHECK_DECL(getopt,stdlib.h unistd.h libc.h)
+ICE_CHECK_DECL(getpeername,sys/types.h sys/socket.h)
+AC_CHECK_FUNCS(getpgrp)
+AC_FUNC_GETPGRP
+ICE_CHECK_DECL(getsockname,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(getsockopt,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(gettimeofday,time.h sys/time.h)
+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(listen,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(lstat,sys/types.h sys/stat.h)
+ICE_CHECK_DECL(malloc,stdlib.h)
+AC_REPLACE_FUNCS(memmove)
+ICE_CHECK_DECL(memmove,string.h strings.h)
+ICE_CHECK_DECL(memset,string.h strings.h)
+AC_CHECK_FUNCS(mkdir)
+ICE_CHECK_DECL(mktemp,stdlib.h)
+AC_REPLACE_FUNCS(mktime)
+ICE_CHECK_DECL(mktime,time.h sys/time.h)
+AC_FUNC_MMAP
+dnl atexit() is prefered, sunos (maybe others?) define on_exit
+AC_CHECK_FUNCS(on_exit)
+ICE_CHECK_DECL(openlog,syslog.h)
+ICE_CHECK_DECL(pclose,stdio.h)
+ICE_CHECK_DECL(perror,stdio.h)
+ICE_CHECK_DECL(printf,stdio.h)
+AC_CHECK_FUNCS(putenv)
+ICE_CHECK_DECL(puts,stdio.h)
+ICE_CHECK_DECL(realloc,stdlib.h)
+ICE_CHECK_DECL(recvfrom,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(remove,stdio.h)
+ICE_CHECK_DECL(rename,stdio.h)
+ICE_CHECK_DECL(rewind,stdio.h)
+AC_CHECK_FUNCS(rmdir)
+ICE_CHECK_DECL(ruserok,netdb.h sys/socket.h libc.h unistd.h)
+ICE_CHECK_DECL(select,sys/types.h sys/socket.h sys/select.h time.h sys/time.h)
+AMANDA_FUNC_SELECT_ARG_TYPE
+ICE_CHECK_DECL(sendto,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(setegid,unistd.h)
+ICE_CHECK_DECL(seteuid,unistd.h)
+AC_CHECK_FUNCS(setmntent)
+ICE_CHECK_DECL(setresgid,unistd.h)
+ICE_CHECK_DECL(setresuid,unistd.h)
+
+dnl arguments for setpgrp or not
+AC_CHECK_FUNC(setpgid, [
+       AC_DEFINE(HAVE_SETPGID,1,[Define if setpgid() is available. ])
+       ICE_CHECK_DECL(setpgid,sys/types.h unistd.h)
+])
+AC_CHECK_FUNC(setpgrp,[AC_FUNC_SETPGRP])
+ICE_CHECK_DECL(setpgrp,sys/types.h unistd.h libc.h)
+
+ICE_CHECK_DECL(setsockopt,sys/types.h sys/socket.h)
+
+AC_CHECK_FUNCS(shmget,
+    [
+       AMANDA_FUNC_SHM_ARG_TYPE
+       case "$FORCE_MMAP" in
+       n | no)
+           AC_DEFINE(HAVE_SYSVSHM,1,[Define if SysV shared-memory functions are available. ])
+         ;;
+       esac
+    ]
+)
+ICE_CHECK_DECL(shmat,sys/types.h sys/ipc.h sys/shm.h)
+ICE_CHECK_DECL(shmctl,sys/types.h sys/ipc.h sys/shm.h)
+ICE_CHECK_DECL(shmdt,sys/types.h sys/ipc.h sys/shm.h)
+ICE_CHECK_DECL(shmget,sys/types.h sys/ipc.h sys/shm.h)
+
+if test "$ac_cv_func_mmap_fixed_mapped" != yes; then
+    case "$FORCE_MMAP" in
+    n | no)
+       if test "$ac_cv_func_shmget" != yes; then
+           AC_MSG_WARN([*** Neither shmget() nor mmap() found!])
+           AC_MSG_WARN([*** This system will not support the Amanda server.])
+           NO_SERVER_MODE=true
+       fi
+      ;;
+    y | ye | yes)
+       AC_MSG_WARN([*** --with-mmap used on a system with no mmap() support!])
+       AC_MSG_WARN([*** This system will not support the Amanda server.])
+       NO_SERVER_MODE=true
+      ;;
+    esac
+fi
+
+ICE_CHECK_DECL(shquote, stdlib.h)
+
+dnl Some systems have snprintf but not vsnprintf.  If either snprintf or
+dnl vsnprintf are missing, then use the snprintf.c we provide.
+ICE_CHECK_DECL(snprintf,stdio.h)
+ICE_CHECK_DECL(vsnprintf,stdio.h)
+if test x"$ice_have_snprintf" != x"yes" ||
+   test x"$ice_have_vsnprintf" != x"yes"; then
+    AC_LIBOBJ([snprintf])
+    if false; then :
+       dnl so that automake includes snprintf.c in the distribution
+       AC_REPLACE_FUNCS(snprintf) 
+    fi
+fi
+
+AC_CHECK_FUNCS(sigaction sigemptyset sigvec)
+ICE_CHECK_DECL(socket,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(socketpair,sys/types.h sys/socket.h)
+ICE_CHECK_DECL(sscanf,stdio.h)
+AC_CHECK_FUNCS(statfs statvfs)
+AC_REPLACE_FUNCS(strerror)
+ICE_CHECK_DECL(strerror,string.h strings.h)
+AC_FUNC_STRFTIME
+AC_REPLACE_FUNCS(strftime)
+ICE_CHECK_DECL(strftime,time.h sys/time.h)
+AC_REPLACE_FUNCS(strncasecmp)
+ICE_CHECK_DECL(strncasecmp,string.h strings.h)
+AC_REPLACE_FUNCS(strstr)
+ICE_CHECK_DECL(syslog,syslog.h)
+ICE_CHECK_DECL(system,stdlib.h)
+ICE_CHECK_DECL(time,time.h sys/time.h)
+ICE_CHECK_DECL(tolower,ctype.h)
+ICE_CHECK_DECL(toupper,ctype.h)
+ICE_CHECK_DECL(ungetc,stdio.h)
+AC_FUNC_VPRINTF
+ICE_CHECK_DECL(vfprintf,stdio.h stdlib.h)
+ICE_CHECK_DECL(vprintf,stdio.h stdlib.h)
+ICE_CHECK_DECL(vsprintf,stdio.h stdlib.h)
+AC_CHECK_FUNC(wait4)
+AC_REPLACE_FUNCS(waitpid)
+AC_REPLACE_FUNCS(strcasecmp)
+ICE_CHECK_DECL(strcasecmp,string.h strings.h)
+
+AC_CHECK_FUNCS(fnmatch)
+
+if test "$ac_cv_func_fnmatch" != yes -a "$USE_QUICK_AND_DIRTY_ESTIMATES" != yes ; then
+    AC_MSG_WARN([--with-qde and no fnmatch -- gnutar exclude files will not work])
+fi
+
+dnl disk device prefixes
+AC_MSG_CHECKING(disk device prefixes)
+dnl Use df to find the mount point for the root filesystem.  Use
+dnl the positional parameters to find the particular line from df
+dnl that contains the root paritition.  We put it in a subshell so
+dnl that the original positional parameters are not messed with.
+dfline=`(
+    df / | while read line; do
+       set -- $line
+       while test $# -gt 0; do
+           if test "$1" = "/"; then
+               echo $line
+               break 2
+           fi
+           shift
+       done
+    done
+) | sed 's/(//' | sed 's/)//' `
+
+dnl Search for the mount point by using expr to find the parameter
+dnl with dev in it.
+mount=`(
+    set -- $dfline
+    while test $# -gt 0; do
+       if expr "$1" : '.*dev' >/dev/null 2>&1; then
+           echo $1
+           break
+       fi
+       shift
+    done
+)`
+
+if test "$DEV_PREFIX" && test "$RDEV_PREFIX"; then
+    AC_MSG_RESULT((predefined) $DEV_PREFIX - $RDEV_PREFIX)
+else
+    if test -d /dev/dsk; then
+       DEV_PREFIX=/dev/dsk/
+       if test -d /dev/rdsk; then
+           RDEV_PREFIX=/dev/rdsk/
+       else
+           RDEV_PREFIX=/dev/dsk/
+       fi
+    elif test -d /dev; then
+       case "$target" in
+           *-sni-sysv4)
+               dev_prefix=/dev/dsk/
+               rdev_prefix=/dev/rdsk/
+               AC_MSG_WARN("*** Run amsinixfixdevs on Sinix systems using VxFS.")
+               ;;
+
+            *)
+               DEV_PREFIX=/dev/
+               # Some systems, notably Linux, do not have raw disk devices
+               # names.  Check this by trying to see if a raw disk device name
+               # exists using the normal raw device path prepended to the
+               # mount point of the root filesystem.
+               if test "$mount"; then
+                   dev_name="/dev/r`basename $mount`"
+                   if test -b $dev_name -o -c $dev_name; then
+                       RDEV_PREFIX=/dev/r
+                   else
+                       RDEV_PREFIX=/dev/
+                   fi
+               else
+                   RDEV_PREFIX=/dev/r
+               fi
+               ;;
+       esac
+    else
+       DEV_PREFIX=/
+       RDEV_PREFIX=/
+    fi
+    AC_MSG_RESULT($DEV_PREFIX - $RDEV_PREFIX)
+fi
+
+AC_DEFINE_UNQUOTED(DEV_PREFIX,"${DEV_PREFIX}",[Define as the prefix for disk devices, commonly /dev/ or /dev/dsk/ ])
+AC_DEFINE_UNQUOTED(RDEV_PREFIX,"${RDEV_PREFIX}",[Define as the prefix for raw disk devices, commonly /dev/r or /dev/rdsk/ ])
+
+case $mount in
+    /dev/vg*)
+       AC_MSG_WARN("*** Run amhpfixdevs on HP-UX systems using /dev/vg??.")
+       ;;
+esac
+
+dnl lock/flock/fcntl
+AC_CACHE_CHECK(
+   [whether posix fcntl locking works],
+   amanda_cv_posix_filelocking,
+   [
+       AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_POSIX_FCNTL
+#include "${srcdir-.}/common-src/amflock.c"
+]])],[
+       amanda_cv_posix_filelocking=yes
+],[
+       amanda_cv_posix_filelocking="no"
+],[
+       amanda_cv_posix_filelocking="no (cannot run test)"
+])
+    rm -f /tmp/conftest.lock
+])
+if test "$amanda_cv_posix_filelocking" = yes; then
+    AC_DEFINE(USE_POSIX_FCNTL,1,[Define to use Posix fcntl for file locking.])
+    HAS_WORKING_FILE_LOCK=1
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    AC_CACHE_CHECK(
+       [whether flock locking works],
+       amanda_cv_flock_filelocking,
+       [
+           AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_FLOCK
+#include "${srcdir-.}/common-src/amflock.c"
+]])],[
+                   amanda_cv_flock_filelocking="yes"
+],[
+                   amanda_cv_flock_filelocking="no"
+],[
+                   amanda_cv_flock_filelocking="no (cannot run test)"
+])
+       rm -f /tmp/conftest.lock
+])
+    if test "$amanda_cv_flock_filelocking" = yes; then
+       AC_DEFINE(USE_FLOCK,1,[Define to use flock for file locking.])
+       HAS_WORKING_FILE_LOCK=1
+    fi
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    AC_CACHE_CHECK(
+       [whether lockf locking works],
+       amanda_cv_lockf_filelocking,
+       [
+           AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_LOCKF
+#include "${srcdir-.}/common-src/amflock.c"
+]])],[
+                   amanda_cv_lockf_filelocking="yes"
+],[
+                   amanda_cv_lockf_filelocking="no"
+],[
+                   amanda_cv_lockf_filelocking="no (cannot run test)"
+])
+       rm -f /tmp/conftest.lock
+])
+    if test "$amanda_cv_lockf_filelocking" = yes; then
+       AC_DEFINE(USE_LOCKF,1,[Define to use lockf for file locking.])
+       HAS_WORKING_FILE_LOCK=1
+    fi
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    AC_CACHE_CHECK(
+       [whether lnlock locking works],
+       amanda_cv_lnlock_filelocking,
+       [
+           AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#undef  ASSERTIONS
+#define CONFIGURE_TEST
+#define USE_LNLOCK
+#include "${srcdir-.}/common-src/amflock.c"
+#include "${srcdir-.}/common-src/alloc.c"
+#include "${srcdir-.}/common-src/error.c"
+#include "${srcdir-.}/common-src/snprintf.c"
+]])],[
+                   amanda_cv_lnlock_filelocking="yes"
+],[
+                   amanda_cv_lnlock_filelocking="no"
+],[
+                   amanda_cv_lnlock_filelocking="no (cannot run test)"
+])
+       rm -f /tmp/conftest.lock
+])
+    if test "$amanda_cv_lnlock_filelocking" = yes; then
+       AC_DEFINE(USE_LNLOCK,1,[Define to use a hard-link based approach for file locking.])
+       HAS_WORKING_FILE_LOCK=1
+    fi
+fi
+
+if test -z "$HAS_WORKING_FILE_LOCK"; then
+    AC_MSG_WARN([*** No working file locking capability found!])
+    AC_MSG_WARN([*** Be VERY VERY careful.])
+fi
+
+dnl extra substitution parameters
+AC_SUBST(CHS)
+AC_SUBST(MTX)
+AC_SUBST(MCUTIL)
+AC_SUBST(ac_n)
+AC_SUBST(ac_c)
+
+AM_CONDITIONAL(WANT_CLIENT, test x"$NO_CLIENT_MODE" != x"true")
+AM_CONDITIONAL(WANT_SAMBA, test ! -z "$SAMBA_CLIENT")
+AM_CONDITIONAL(WANT_RESTORE, test x"$NO_RESTORE_MODE" != x"true")
+AM_CONDITIONAL(WANT_SERVER, test x"$NO_SERVER_MODE" != x"true")
+AM_CONDITIONAL(WANT_RECOVER, test x"$NO_RECOVER_MODE" != x"true" && test x"$NO_CLIENT_MODE" != x"true")
+AM_CONDITIONAL(WANT_TAPE, test x"$NO_SERVER_MODE" != x"true" || test x"$NO_RESTORE_MODE" != x"true")
+AM_CONDITIONAL(WANT_AMPLOT, test x"$NO_AMPLOT_MODE" != x"true")
+AM_CONDITIONAL(WANT_CHG_SCSI, test x"$NO_SCSI_CHANGER_MODE" != x"true")
+AM_CONDITIONAL(WANT_CHIO_SCSI, test x"$NO_CHIO_CHANGER_MODE" != x"true")
+AM_CONDITIONAL(WANT_RUNTIME_PSEUDO_RELOC, test x"$NEED_RUNTIME_PSEUDO_RELOC" = x"true")
+AM_CONDITIONAL(WANT_SETUID_CLIENT, test x"$NEED_SETUID_CLIENT" != x"false")
+
+case "${FORCE_USE_RUNDUMP-${USE_RUNDUMP}}" in
+y |  ye | yes) AC_DEFINE(USE_RUNDUMP,1,[Define to invoke rundump (setuid-root) instead of DUMP program directly. ]);;
+esac
+
+# This is necessary so that .o files in LIBOBJS are also built via
+# the ANSI2KNR-filtering rules.
+LIB@&t@OBJS=`echo "$LIB@&t@OBJS" |
+             sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'`
+LTLIBOBJS=`echo "$LIB@&t@OBJS" |
+           sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
+AC_SUBST(LTLIBOBJS)
+
+LTALLOCA=`echo "$ALLOCA" | sed 's/\.'"${ac_objext}"'/\.lo/g'`
+AC_SUBST(LTALLOCA)
+
+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             \
+                                                                       \
+       common-src/versuff.c            common-src/Makefile             \
+                                                                       \
+       example/amanda.conf             example/Makefile                \
+       example/amanda.conf.chg-scsi    example/chg-scsi-linux.conf     \
+       example/chg-scsi-solaris.conf   example/chg-scsi-hpux.conf      \
+       example/chg-mcutil.conf                                         \
+                                                                       \
+       man/amadmin.8                   man/amanda.8                    \
+       man/amcheck.8                   man/amcheckdb.8                 \
+       man/amcleanup.8                 man/amdump.8                    \
+       man/amflush.8                   man/amlabel.8                   \
+       man/amoverview.8                man/amrecover.8                 \
+       man/amrmtape.8                  man/amtoc.8                     \
+       man/amverify.8                  man/Makefile                    \
+       man/amstatus.8                  man/amreport.8                  \
+       man/amgetconf.8                 man/amverifyrun.8               \
+       man/amtapetype.8                                                \
+                                                                       \
+       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                                       \
+                                                                       \
+       tape-src/Makefile                                               \
+                                                                       \
+       config/Makefile                 Makefile])
+AC_OUTPUT
diff --git a/contrib/README b/contrib/README
new file mode 100644 (file)
index 0000000..7b61387
--- /dev/null
@@ -0,0 +1,14 @@
+This directory contains odds and ends that have been contributed by
+other Amanda users.  They are made available on a completely "as-is"
+basis for the benefit of the Amanda community.
+
+========
+dbbackup
+========
+
+The dbbackup.* files provide a "hot" backup system for an Oracle database
+to a disk partition, which can then be backed up with Amanda.
+
+Author: Todd M. Helfter
+        Purdue University Computing Center
+        tmh@purdue.edu
diff --git a/contrib/dbbackup.README b/contrib/dbbackup.README
new file mode 100755 (executable)
index 0000000..baccd88
--- /dev/null
@@ -0,0 +1,65 @@
+
+                               dbbackup
+
+
+dbbackup is a set of scripts to automate Oracle hot backups using tcl
+via oratcl.  It is currently used on 24x7 systems on several platforms,
+including Solaris2.5/2.6 and AIX.  It has been tested and used with both
+Oracle 7 and Oracle 8.
+
+I recommend the most stable release of Tcl (currently 8.0p2) and
+Oratcl 2.5
+
+In our oracle implementation, we have a single disk '/opt/oracle/backup'
+who's sole purpose is to hold the database backups.  We point our archive
+log destination there, so all archived redo logs are in one spot and
+we run a hot backup nightly to copy all the datafiles and the control
+file there as well.  Necessarily, the /opt/oracle/backup disk must be
+big enough to hold all of this.
+
+We use the Amanda backup system (www.amanda.org) to handle backing up
+the disk to tape.
+
+
+Simply put, the ksh script sets up environment for the tcl script, which
+does the following:
+       - for each tablespace in the database
+               - identify all datafiles belonging to that tablespace 
+               - set the tablespace to backup mode
+               - copy the datafiles to the backup location
+               - set the tablespace to regular mode
+       - switch the log file so any changes made during backup get archived
+       - back up the control file
+
+There are no fancy installation scripts as of yet.  Here is a short
+summary of what is needed.
+
+1.  Root user creates a system backup account.
+2.  Oracle DBA runs dbbackup.sql as oracle user "sys" to:
+               - create a role "backup_role"
+               - grant minimal system privileges to backup_role (i.e.
+                 manage tablespace)
+                       *NOTE* these are powerful privileges. but necessary
+               - grant minimal necessary table privileges to backup_role
+                 (i.e. dba_tablespace)
+               - create the backup user from step 1
+               - grant backup_role to the backup user
+3.  configure  - change dbbackup.ksh to find the oracle script "dbhome",
+                 set ORACLE_SID and optionally set the dbbackup
+                 administration area (location of logs and dbbackup.ksh)
+                 and user who will get the E-mail reports.
+               - change dbbackup.tcl to find the backup destination
+                 (variables df_dest and cf_dest)
+4.  Root user needs to install dbbackup.ksh.  The dbbackup.tcl script must
+    be installed in $adm/dbbackup.tcl (adm is defined in dbbackup.ksh).
+5.  Root user needs to add a cron job to trim old archive logs (6 days worth).
+               'dbbackup.cron' is a sample cron entry
+               *NOTE* failure to add crontab fills the disk real fast.
+               *NOTE* our archive logs are [sid]####.dbf  
+6. Root user needs to configure the backup system to call 'dbbackup.ksh'
+   as the backup user.
+
+
+Todd M. Helfter
+Purdue University Computing Center
+tmh@purdue.edu
diff --git a/contrib/dbbackup.ksh b/contrib/dbbackup.ksh
new file mode 100755 (executable)
index 0000000..7eb9029
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/ksh
+# 
+# Wrapper script to set environment and run dbbackup.tcl.
+# 
+
+#  user defined variables below
+adm=/var/backup
+mailuser=backup
+dbhomescript=/opt/oracle/bin/dbhome
+
+export ORACLE_SID=cc
+
+#  no need to change anything below here
+pgm=${0##*/}
+
+if [[ ! -x ${adm}/dbbackup.tcl ]]
+then
+       msg="${pgm}: cannot execute ${adm}/dbbackup.tcl"
+       /usr/bin/mailx -s "${msg}" ${mailuser} < /dev/null
+       print -u2 ${msg}
+       exit 1
+fi
+
+if [[ ! -x $dbhomescript ]]
+then
+       msg="${pgm}: cannot execute $dbhomescript"
+       /usr/bin/mailx -s "${msg}" ${mailuser} < /dev/null
+       print -u2 ${msg}
+       exit 1
+fi
+
+timestamp=$(date "+%Y-%m-%d.%T")
+log=${adm}/dbbackup.log.${timestamp}
+err=${adm}/dbbackup.err.${timestamp}
+rm -f ${log} ${err}
+
+find ${adm}/. -name "dbbackup.log.*" -mtime +30 -print | xargs rm -f
+find ${adm}/. -name "dbbackup.err.*" -mtime +30 -print | xargs rm -f
+
+export ORACLE_HOME=$($dbhomescript "$ORACLE_SID")
+export ORA_NLS=$ORACLE_HOME/ocommon/nls/admin/data
+export LD_LIBRARY_PATH=$ORACLE_HOME/lib
+
+( ${adm}/dbbackup.tcl 2>&1 || touch ${err} 2>&1 ) | tee $log
+
+if [[ -f ${err} ]]
+then
+       msg="${pgm}: dbbackup.tcl failed"
+       /usr/bin/mailx -s "${msg}" ${mailuser} < ${log}
+       print -u2 ${msg}
+       exit 1
+fi
+
+exit 0
diff --git a/contrib/dbbackup.sql b/contrib/dbbackup.sql
new file mode 100755 (executable)
index 0000000..87a51e4
--- /dev/null
@@ -0,0 +1,23 @@
+-- ==================================================== --
+--     dbbackup.sql                                    --
+--                                                     --
+--     This script is run as user "sys"                --
+--                                                     --
+--     creates user "backup" identified externally     --
+--     creates role "backup_role" with permisssions    --
+--     grants role "backup_role" to user "backup"      --
+--                                                     --
+-- ==================================================== --
+connect internal
+
+create role backup_role;
+grant create session to backup_role;
+grant alter system to backup_role;
+grant alter database to backup_role;
+grant manage tablespace to backup_role;
+grant select on dba_tablespaces to backup_role;
+grant select on dba_data_files to backup_role;
+grant select on v_$log to backup_role;
+
+create user backup identified externally;
+grant backup_role to backup;
diff --git a/contrib/dbbackup.tcl b/contrib/dbbackup.tcl
new file mode 100755 (executable)
index 0000000..fa43f87
--- /dev/null
@@ -0,0 +1,230 @@
+#!/opt/tcl8.3.0/bin/tclsh8.3
+
+#  .-------------.------------------------------------------------------.
+#  |  module     |  dbbackup.tcl                                        |
+#  `-------------^------------------------------------------------------'
+
+#  .--------------------------------------------------------------------.
+#  |                           Revisions                               |
+#  |--------------------------------------------------------------------|
+#  |  07/25/96 (TMH) eliminated the need for a library file.           |
+#  |  02/10/97 (TMH) converted to tcl7.6, oratcl 2.4.                  |
+#  |  12/02/98 (TMH) eliminate all pipes to /bin/sh for final release  | 
+#  `--------------------------------------------------------------------'
+
+#  .--------------------------------------------------------------------.
+#  |            Copyright (c) 1998, Purdue University                   |
+#  |                     All rights reserved.                           |
+#  `--------------------------------------------------------------------'
+
+#  .--------------------------------------------------------------------.
+#  |  Redistribution and use in source and binary forms are permitted   |
+#  |  provided that:                                                    |
+#  |                                                                    |
+#  | (1) source distributions retain this entire copyright notice and   |
+#  |     comment, and                                                   |
+#  | (2) distributions including binaries display the following         |
+#  |      acknowledgement:                                              |
+#  |                                                                    |
+#  |   "This product includes software developed by Purdue University." |
+#  | in the documentation or other materials provided with the          |
+#  | distribution and in all advertising materials mentioning features  |
+#  | or use of this software.                                           |
+#  |                                                                    |
+#  |   The name of the University may not be used to endorse or promote |
+#  | products derived from this software without specific prior written |
+#  | permission.                                                        |
+#  |                                                                    |
+#  | THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR     |
+#  | IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED     |
+#  | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR      |
+#  | PURPOSE.                                                           |
+#  `--------------------------------------------------------------------'
+
+package require -exact Oratcl 2.7
+
+set uidpswd /
+set df_dest /opt/oracle/backup
+set cf_dest [file join $df_dest "ctl$env(ORACLE_SID).ctl"]
+
+set cur {}
+set lda {}
+
+
+#  .--------------------------------------------------------------------.
+#  |  sysdate                                                          |
+#  `--------------------------------------------------------------------'
+proc sysdate {} {
+       return [clock format [clock seconds] -format {%c}]
+}
+
+
+#  .-------------.------------------------------------------------------.
+#  |  procedure  |  ora_Connect                                                |
+#  |  date       |  (09/02/94)                                          |
+#  `-------------^------------------------------------------------------'
+proc ora_Connect {} {
+       global uidpswd
+       global cur
+       global lda
+
+       set retcode [catch {set lda [oralogon ${uidpswd}]}]
+       if {$retcode == 0} {
+               set cur [oraopen $lda]
+       }
+       return $retcode
+}
+
+
+#  .-------------.------------------------------------------------------.
+#  |  procedure  |  ora_Disconnect                                     |
+#  |  author     |  Todd M. Helfter                                     |
+#  |  date       |  (09/02/94)                                          |
+#  `-------------^------------------------------------------------------'
+proc ora_Disconnect {} {
+       global lda
+       return [catch {oralogoff $lda }]
+}
+
+
+#  .-------------.------------------------------------------------------.
+#  |  procedure  |  print_log                                          |
+#  `-------------^------------------------------------------------------'
+proc print_log {} {
+       global cur oramsg
+
+       set log_min {}
+       set log_max {}
+       set sql {select min(sequence#), max(sequence#) from v$log}
+       if {[catch {orasql $cur $sql}] == 0} {
+               orafetch $cur "set log_min @1; set log_max @2"
+       }
+       puts stdout [format "\nOldest online log sequence\t%s" $log_min]
+       puts stdout [format "Current log sequence\t\t%s\n" $log_max]
+       flush stdout
+}
+
+
+#  .-------------.------------------------------------------------------.
+#  |  procedure  |  ora_SQL                                            |
+#  `-------------^------------------------------------------------------'
+proc ora_SQL {sql_str} {
+       global cur oramsg
+
+       set dbret [catch {orasql $cur $sql_str}]
+       if {$dbret != 0} {
+               puts stdout $oramsg(errortxt)
+               flush stdout
+       } else {
+               orafetch $cur {
+                       puts stdout @0
+                       flush stdout
+               }
+       }
+}
+
+
+#  .--------------------------------------------------------------------.
+#  |  query_info                                                       |
+#  `--------------------------------------------------------------------'
+proc query_info {} {
+       global cur ts_list df_list oramsg uidpswd
+
+       set ts_list {}
+       if {[ora_Connect] == 0} {
+               set sql0 "SELECT tablespace_name FROM sys.dba_tablespaces"
+               if {[catch {orasql $cur $sql0}] == 0} {
+                       orafetch $cur {lappend ts_list @0}
+               }
+       } else {
+               puts stdout $oramsg(errortxt)
+               flush stdout
+               exit 1
+       }
+
+       foreach ts_name $ts_list {
+               set df_list($ts_name) {}
+               set sql1 "SELECT file_name FROM sys.dba_data_files \
+                       where tablespace_name = '$ts_name'"
+               if {[catch {orasql $cur $sql1}] == 0} {
+                       orafetch $cur {lappend df_list($ts_name) @0}
+               } else {
+                       puts stdout $oramsg(errortxt)
+                       flush stdout
+                       exit 1
+               }
+       }
+}
+
+
+#  .--------------------------------------------------------------------.
+#  |  print_info                                                       |
+#  `--------------------------------------------------------------------'
+proc print_info {} {
+       global ts_list df_list
+
+       foreach ts_name $ts_list {
+               puts stdout "ts_name : $ts_name"
+               flush stdout
+               foreach df_name $df_list($ts_name) {
+                       puts stdout "  df_name : $df_name"
+                       flush stdout
+               }
+       }
+}
+
+
+#  .--------------------------------------------------------------------.
+#  |  ora_Backup                                                       |
+#  `--------------------------------------------------------------------'
+proc ora_Backup {} {
+       global ts_list df_list df_dest cf_dest
+
+       print_log
+
+       foreach ts_name $ts_list {
+
+               puts stdout "[sysdate] | begin online backup for : $ts_name"
+               flush stdout
+               ora_SQL "alter tablespace $ts_name begin backup"
+
+               foreach df_name $df_list($ts_name) {
+                       puts stdout "[sysdate] | copying $df_name to $df_dest."
+                       flush stdout
+                       file copy -force -- $df_name $df_dest
+               }
+               puts stdout "[sysdate] | end online backup for : $ts_name"
+               flush stdout
+               ora_SQL "alter tablespace $ts_name end backup"
+       }
+       puts stdout "[sysdate] | switching logfile."
+       flush stdout
+       ora_SQL {alter system switch logfile}
+
+       print_log
+
+       puts stdout "[sysdate] | copying control file to $cf_dest."
+       flush stdout
+       ora_SQL "alter database backup controlfile to '$cf_dest' reuse"
+}
+
+
+#  .-------------.------------------------------------------------------.
+#  |  procedure  |  main                                                |
+#  |  purpose    |  scan database and report results to parent window          |
+#  |  author     |  Todd M. Helfter                                     |
+#  |  date       |  (10/13/94)                                          |
+#  `-------------^------------------------------------------------------'
+proc main {} {
+       global cur uidpswd oramsg ts_list df_list
+
+       query_info
+       print_info
+
+       ora_Backup
+       ora_Disconnect
+}
+
+
+main
+exit 0
diff --git a/contrib/mkamandisk b/contrib/mkamandisk
new file mode 100644 (file)
index 0000000..aad10ca
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# This script prepares an IOmega disk for use with amanda.
+# More precisely, it
+# - formats the disk, checking for bad sectors
+# - mounts the disk and adds a data subdirectory
+# - makes user amanda owner of this data sub directory
+# - calls amlabel to label the disk
+# - unmounts and ejects the disk.
+# 
+# This shell script is not generally usable as is, 
+# because it is relying on a couple of settings of personal taste, such as
+# - IOmega disks are partitioned and the fourth primary partition 
+#   is taking the whole disk. So the disk is visible as /dev/sda4.
+# - I am preferring to use an ext2 filesystem on the disk 
+#   (rather then a dos or vfat file system)
+# - I am doing a chown of the data sub directory such that - depending 
+#   on the umask setting - only user amanda and root can see 
+#   the files written to the disk.
+
+# It has to be called as root
+
+if [ "$#" -lt "2" ]
+       then
+       echo "Usage : $0 <backup set> <disk label>"
+       exit 1
+fi
+
+backup="$1"
+label="$2"
+
+echo "insert tape $2 into slot and press return" 
+read ANSWER
+
+mkfs.ext2 -c -L $label /dev/iomega
+
+echo "mounting disk ..."
+mount /dev/iomega
+if [ ! -d /mnt/iomega/lost+found ]
+       then
+       echo "mount did not work properly - please investigate"
+       exit 1
+fi
+
+echo "adding data subdirectory ..."
+cd /mnt/iomega
+mkdir data
+chown -R amanda:disk .
+if [ -n "$label" ]
+       then
+       echo "attempting to write amanda disk label"
+       su - amanda -c "/usr/sbin/amlabel $backup $label"
+fi
+
+echo "preparing to eject disk ..."
+cd >/dev/null 2>&1
+eject /mnt/iomega
+
+echo "please don't forget to label with $backup $label"
diff --git a/contrib/set_prod_link.pl b/contrib/set_prod_link.pl
new file mode 100644 (file)
index 0000000..d299615
--- /dev/null
@@ -0,0 +1,144 @@
+#!/usr/local/bin/perl
+# ========================================================================
+# @(#) $Id: set_prod_link.pl,v 1.1.2.1 1999/11/02 21:29:56 oliva Exp $
+# ------------------------------------------------------------------------
+# $Source: /cvsroot/amanda/amanda/contrib/set_prod_link.pl,v $
+# ------------------------------------------------------------------------
+# Description:
+#   
+#   When installing AMANDA with the option --with-suffix you can use this
+#   script to set the a symbolic link from the productive name of the
+#   files to this special version.
+#   This way you can switch on the fly, from one version to an other.
+#
+#   Actually I would advice to use the option --prefix and install the
+#   the whole software in different paths.
+#
+#   But if you want for example install a new version in the same
+#   directory you can use it.
+#
+# -----------------------------------------------------------------------
+# Author: Ricardo Malta, rmalta@bigfoot.com
+# -----------------------------------------------------------------------
+# History:
+#
+# $Log: set_prod_link.pl,v $
+# Revision 1.1.2.1  1999/11/02 21:29:56  oliva
+# * contrib/set_prod_link.pl: Create the links for a configuration
+# with --with-suffix.
+#
+#
+# ========================================================================
+
+$debug = 0;
+
+if ($ARGV[0] ne "doit") {
+       print <<"EOD";
+usage: $0 doit
+
+       Go to the directory where you have compiled AMANDA.
+       Call this programm with the parameter \"doit\".
+
+EOD
+       exit 1;
+}
+
+# ------------------------------------------------------------------------
+# Open the Makefile and search for the entries we need for doing the job.
+# ------------------------------------------------------------------------
+open(FD,"<Makefile") || die "Cannot open Makefile: $!\n";
+while (<FD>) {
+       $suffix  = (split(/\s*,\s*/))[2] if /^\s*transform\s*=/;
+       $rootdir = (split(/=\s*/))[1] if /^\s*prefix\s*=/;
+       last if $suffix && $suffix;
+}
+close(FD);
+chomp $rootdir;
+die "Cannot find line containing \"transform =\" in Makefile.\n" if (!$suffix);
+die "Cannot find line containing \"prefix =\" in Makefile.\n" if (!$rootdir);
+
+# ------------------------------------------------------------------------
+# Last chance ....
+# ------------------------------------------------------------------------
+print "Starting setting the links to productive version:
+    Directory: $rootdir
+    Suffix   : $suffix
+Confirm with <yes>: ";
+chomp($dummy = <STDIN>);
+die "\nAborting ...\n" if ($dummy ne "yes");
+print "\n";
+
+# ------------------------------------------------------------------------
+# Now do the job
+# ------------------------------------------------------------------------
+$CUR_DIR = "$rootdir";
+Make_Prod_Link($rootdir,$suffix) || die "Cannot create links under $rootdir\n";
+
+# ------------------------------------------------------------------------
+# We are done ... get out of here
+# ------------------------------------------------------------------------
+exit 0;
+
+# ************************************************************************
+#                    F U N C T I O N S
+# ************************************************************************
+
+# ------------------------------------------------------------------------
+# Scan the directory for AMANDA-Entries
+# ------------------------------------------------------------------------
+sub Make_Prod_Link {
+       my ($prefix,$suffix) = @_;
+
+       # --------------------------------------------------
+       # Just for info
+       # --------------------------------------------------
+       my $cur_dir = $CUR_DIR;
+       print "-> $CUR_DIR\n";
+
+       # --------------------------------------------------
+       # Change to given directory and read the inodes
+       # --------------------------------------------------
+       chdir $prefix or do { warn "$CUR_DIR: $!\n";
+                             return;
+                           };
+       opendir(DIR,".") or do { warn "$CUR_DIR: $!\n";
+                                return;
+                               };
+       my @inodes = grep(!/^\.$|^\.\.$/,readdir(DIR));
+
+       # --------------------------------------------------
+       # For each inode check if it is a directory or an
+       # amanda file
+       # --------------------------------------------------
+       foreach my $inode (@inodes) {
+               if (-d $inode) {
+                       # ----------------------------------
+                       # For a directory -> recursion
+                       # ----------------------------------
+                       $CUR_DIR .= "/".$inode;
+                       Make_Prod_Link($inode,$suffix) or return;
+                       chdir ".." or do { warn "Cannot get back from $inode: $!\n";
+                                          return;
+                                        };
+                       $CUR_DIR = $cur_dir;
+               }
+               # -----------------------------------------------------
+               # Create a symbolic link unless the file already exists
+               # -----------------------------------------------------
+               if (substr($inode,-length($suffix)) eq $suffix) {
+                       my $prog_name = substr($inode,0,-length($suffix));
+                       if (-e $prog_name && ! -l $prog_name) {
+                               warn "Unexpected real file found: $CUR_DIR/$prog_name\n";
+                               return;
+                       }
+                       unlink $prog_name;
+                       symlink($inode,$prog_name) or do { warn "Cannot create symbolical link for $prog_name -> $inode: $!\n";
+                                                          return;
+                                                        };
+                       print "    $prog_name -> $inode\n";
+               } else {
+                       print "let it untouched: $inode\n" if $debug;
+               }
+       }
+       1;
+}
diff --git a/contrib/sst/Makefile b/contrib/sst/Makefile
new file mode 100644 (file)
index 0000000..53bf09e
--- /dev/null
@@ -0,0 +1,16 @@
+all: sst sstest
+
+sst: sst.c
+       $(CC) -D_KERNEL -c sst.c
+       ld -r sst.o -o sst
+
+sstest: sstest.c
+       $(CC) -o sstest sstest.c
+
+install: sst
+       cp sst /usr/kernel/drv
+       cp sst.conf /usr/kernel/drv
+#      echo "type=sample_driver;name=sst;minor=character\trsst\A1" >> /etc/devlink.tab
+
+clean:
+       rm sst sstest
diff --git a/contrib/sst/README b/contrib/sst/README
new file mode 100644 (file)
index 0000000..7fd30d8
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1996,1997, by Sun Microsystems, Inc.
+ * All Rights Reserved
+ */
+
+       ident   "@(#)README 1.11        97/09/09 SMI"
+
+DRIVER NAME:
+       sst - Simple SCSI Target driver
+
+ARCHITECTURES:
+       SPARC and x86
+
+DESCRIPTION OF DRIVER:
+       This driver is intended as an example of programming a SCSA
+       target driver for Solaris 2.X; it is not intended for any
+       particular device.
+
+       This driver has been modified to be 64-bit ready.  In
+       particular it provides an example of how an LP64 driver
+       can manage an ioctl from an ILP32 application.  Refer to
+        SunOS 5.6 Writing Device Drivers, Appendix F for more
+       information.
+
+       Source Files
+       -------------
+
+       sst.c           driver source
+       sst_def.h       driver definitions
+       sst.conf        driver configuration file
+       sstest.c        driver test program
+
+NOTE:
+       Areas where you may need to change this code or add your own to
+       deal with your specific devices are marked "Note".
+       Other warnings are marked "WARNING".
+
+DISCLAIMER:
+        This driver provides an example of programming using the SCSA 
+       DDI/DDK interfaces for Solaris target drivers; it is not intended 
+       for any particular device, although it has been tested on disk 
+       and tape drives.  It is meant to be a skeleton that can be 
+       used as a basis for a real-world driver.  
+
+SYSTEM REQUIREMENTS:
+       The driver requires a SCSI target device to operate.
+
+COMPILING/LOADING:
+       To compile and link the driver:
+
+       use the Makefile provided in the driver subdirectory (sst); the
+       executable files will be built in an architecture-specific
+       subdirectory depending on the architecture of the build machine
+       (i.e., sst/sparc)
+
+       to compile and link without using the Makefile:
+
+       % cc -D_KERNEL -c sst.c
+       % ld -r sst.o -o sst
+
+       To install:
+
+       1. Copy the module (sparc/sst) and config file (sst.conf)
+          into /usr/kernel/drv
+
+       2. (optional) Add an entry to /etc/devlink.tab, of the form:
+
+               type=sample_driver;name=sst;minor=character        rsst\A1
+
+          This will cause devlinks(1M) to create link(s) to /devices with
+          names of the form "/dev/rsstX" where X is the SCSI target number
+          (the target number is "5" in the sst.conf file included in the
+          DDK; you can change it to refer to an appropriate target number
+          for the target device on your system).
+
+       3. Run add_drv(1M).
+
+               # add_drv sst
+
+       To compile the test program:
+
+       run "make sstest" in the sst directory; the executable file will be 
+       built in an architecture-specific subdirectory depending on the 
+       architecture of the build machine (sst/sparc or sst/i386)
+
+       The test program takes as arguments the full path to the device
+       file (e.g., /dev/sst0 or /devices/mc/mcis@3540,0/sst@3,0:character)
+       and a command (see the sstest program's usage message for available
+       commands)
+
+       Setting kernel variables:
+           Variables can be explicitly set from the /etc/system file, by
+           adding an entry of the form
+
+               "set sst:<variable name>=<value>"
+
+           The /etc/system file is read only once at boot time, if you change
+           it you must reboot for the change to take effect.
+
+           Alternatively, you can use adb to set variables and debug as
+           follows:
+
+               # adb -kw /dev/ksyms /dev/mem
+
+           Or, if you booted under kadb, you can set the a variable from the
+           kadb prompt. For example, the following command will set the
+           variable sst_debug to the value 3 (maximum debugging messages):
+
+               kadb[0]: sst_debug:W 3
+          
+REFERENCES:
+       
+        SunOS 5.6 Writing Device Drivers
diff --git a/contrib/sst/README.Amanda b/contrib/sst/README.Amanda
new file mode 100644 (file)
index 0000000..d0a5441
--- /dev/null
@@ -0,0 +1,66 @@
+These are notes specific to using sst with Amanda on Solaris.
+
+John R. Jackson
+21-Nov-2000
+
+==============
+Access as root
+==============
+
+A change was made to the sst.c source code to allow access from non-root
+users.  It #if's out a call to drv_priv() that checked against UID 0
+(look for EPERM in the code).  Since Amanda does not normally run as
+root, this was a problem.  Use the file system permissions on /dev/rsst*
+to control access.
+
+========================
+Using the GNU C compiler
+========================
+
+If you build sst with the GNU C compiler for a 32 bit kernel (see below
+for 64 bit kernel notes), you may get warnings like this:
+
+  warning: passing arg 1 of `timeout' from incompatible pointer type
+  .../include/va-sparc.h:29: warning: `va_start' redefined
+  .../include/va-sparc.h:29: warning: `va_end' redefined
+  .../include/va-sparc.h:29: warning: `va_arg' redefined
+  .../include/stdarg.h:163: warning: redefinition of `va_list'
+
+These may all be ignored.
+
+A change was made to the sst.c source code to get around the following
+error:
+
+  `__builtin_va_alist' undeclared
+
+It adds a #include of stdarg.h if __GNUC__ is #define'd.
+
+============================
+Building for a 64 bit kernel
+============================
+
+The sst driver build instructions are for a 32 bit kernel.  If you want
+to build for a 64 bit kernel, compile it like this:
+
+  cc -D_KERNEL -D_SYSCALL32 -xarch=v9 -c sst.c
+
+Drivers for 64 bit kernels go in /usr/kernel/drv/sparcv9 instead of
+/usr/kernel/drv.  However their .conf files still go in /usr/kernel/drv,
+regardless of bit size.
+
+At the time this is being written, only the Sun C compiler is able to
+(reliably) build kernel drivers for 64 bit architectures.  GNU C is not
+yet up to the task.
+
+==================
+Using sgen instead
+==================
+
+Solaris 8 comes with a new driver, sgen, that provides raw SCSI access
+ala sst, but with (presumably) better long term support (since sst is
+intended only as a development starting point).  At the time this is
+being written, the chg-scsi changer reportedly works with sgen, but be
+sure and read the sgen(7D) man page for instructions on setting it up.
+In particular, you must edit sgen.conf to get the device entries created.
+Also, the default permissions only allow root access, so you'll need to
+open them up just enough to allow Amanda to issue commands.
diff --git a/contrib/sst/sst.c b/contrib/sst/sst.c
new file mode 100644 (file)
index 0000000..3c0efed
--- /dev/null
@@ -0,0 +1,2538 @@
+/*
+ * Copyright (c) 1997, by Sun Microsystems, Inc.
+ * All Rights Reserved
+ */
+
+/*
+ * sst.c - Simple SCSI Target driver; a template character SCSA target
+ *        driver for Solaris 2.x.
+ *
+ * This file is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify this file without charge, but are not authorized to
+ * license or distribute it to anyone else except as part of a product
+ * or program developed by the user.
+ *
+ * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * This file is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even
+ * if Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 901 San Antonio Rd
+ * Palo Alto, California  94303
+ *
+ * ------------------------------------------------------------------
+ *
+ * This driver is intended as an example of programming a SCSA
+ * target driver for Solaris 2.X; it is not intended for any particular
+ * device.
+ *
+ * Areas where you may need to change this code or add your own to
+ * deal with your specific device are marked "Note".
+ * Other warnings are marked "WARNING"
+ *
+ * To compile:
+ *     % cc -D_KERNEL -c sst.c
+ *     % ld -r sst.o -o sst
+ *
+ * To install:
+ * 1. Copy the module (sst) and config file (sst.conf) into /usr/kernel/drv
+ * 2. Add an entry to /etc/devlink.tab, of the form:
+ *     "type=sample_driver;name=sst;minor=character        rsst\A1"
+ *    This will cause devlinks(1M) to create link(s) to /devices with
+ *    names of the form "/dev/rsstX" where X is the SCSI target number.
+ * 3. Run add_drv(1M).
+ *
+ * Setting variables
+ *     Variables can be explicitly set from the /etc/system file, by
+ *     adding an entry of the form
+ *             "set sst:<variable name>=<value>"
+ *     Alternatively, you can use adb to set variables and debug as
+ *     follows:
+ *             # adb -kw /dev/ksyms /dev/mem
+ *     The /etc/system file is read only once at boot time, if you change
+ *     it you must reboot for the change to take effect.
+ */
+
+#pragma        ident   "@(#)sst.c 1.23 97/10/03 SMI"
+
+/*
+ * Includes, Declarations and Local Data
+ */
+
+#include <sys/scsi/scsi.h>
+#include <sys/file.h>
+#ifdef __GNUC__
+#include <stdarg.h>
+#endif
+
+#include "sst_def.h"
+
+/*
+ * Local Function Prototypes
+ */
+static int sst_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p);
+static int sst_close(dev_t dev, int flag, int otyp, cred_t *cred_p);
+static int sst_read(dev_t dev, struct uio *uio, cred_t *cred_p);
+static int sst_write(dev_t dev, struct uio *uio, cred_t *cred_p);
+static int sst_aread(dev_t dev, struct aio_req *aio, cred_t *credp);
+static int sst_awrite(dev_t dev, struct aio_req *aio, cred_t *credp);
+static int sst_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
+
+static int sst_strategy(struct buf *bp);
+static int sst_ioctl_cmd(dev_t, struct uscsi_cmd *, enum uio_seg,
+    enum uio_seg, int mode);
+
+static int sst_unit_ready(dev_t dev);
+static void sst_done(struct scsi_target *targ, struct buf *bp);
+static void sst_restart(caddr_t arg);
+static void sst_callback(struct scsi_pkt *pkt);
+static struct scsi_pkt *sst_make_cmd(struct scsi_target *targ, struct buf *bp,
+    struct scsi_pkt *pktp);
+static void sst_fill_cdb(struct scsi_pkt *pkt, struct scsi_target *targ,
+    struct buf *bp, u_int flags);
+static int sst_handle_incomplete(struct scsi_target *targ);
+static int sst_handle_arq(struct scsi_pkt *pktp, struct scsi_target *targ,
+    struct buf *bp);
+static int sst_handle_sense(struct scsi_target *targ, struct buf *bp);
+static int sst_check_error(struct scsi_target *targ, struct buf *bp);
+static void sst_log(struct scsi_device *devp, int level, const char *fmt, ...);
+static void hex_print(char *msg, void *cptr, int len);
+static void sst_dump_cdb(struct scsi_target *tgt, struct scsi_pkt *pkt,
+    int cdblen);
+
+/*
+ * Local Static Data
+ */
+static int sst_io_time         = SST_IO_TIME;
+static int sst_retry_count     = SST_RETRY_COUNT;
+static void *sst_state;
+
+/*
+ * Errors at or above this level will be reported
+ */
+static int32_t sst_error_reporting = SCSI_ERR_RETRYABLE;
+
+/*
+ * Enable the driver debugging code if DEBUG is defined (DEBUG also
+ * enables other debugging code, e.g. ASSERT statements).
+ */
+#ifdef DEBUG
+#define        SST_DEBUG
+#endif DEBUG
+
+
+/*
+ * Debug message control
+ * Debug Levels:
+ *     0 = no messages
+ *     1 = Errors
+ *     2 = Subroutine calls & control flow
+ *     3 = I/O Data (verbose!)
+ * Can be set with adb or in the /etc/system file with
+ * "set sst:sst_debug=<value>"
+ * turn on diagnostics if DEBUG is defined (DEBUG also enables
+ * other debugging code, e.g. ASSERT statements).
+ */
+
+#ifdef SST_DEBUG
+static int sst_debug = 3;
+static int sst_debug_cdb = 1;
+#else
+static int sst_debug = 0;
+static int sst_debug_cdb = 0;
+#endif /* SST_DEBUG */
+
+#define        SST_DUMP_CDB(tgt, pkt, cdblen)                          \
+       if (sst_debug_cdb) {                                    \
+               sst_dump_cdb((tgt), (pkt), (cdblen));           \
+       }
+
+/*
+ * Array of commands supported by the device, suitable for
+ * scsi_errmsg(9f)
+ * Note: Add or remove commands here as appropriate for
+ *      your device.
+ */
+static struct scsi_key_strings sst_cmds[] = {
+       0x00, "test unit ready",
+       0x01, "rezero/rewind",
+       0x03, "request sense",
+       0x04, "format",
+       0x05, "read block limits",
+       0x07, "reassign",
+       0x08, "read",
+       0x0a, "write",
+       0x0b, "seek",
+       0x0f, "read reverse",
+       0x10, "write file mark",
+       0x12, "inquiry",
+       0x13, "verify",
+       0x14, "recover buffered data",
+       0x15, "mode select",
+       0x16, "reserve",
+       0x17, "release",
+       0x18, "copy",
+       0x19, "erase tape",
+       0x1a, "mode sense",
+       0x1b, "start/stop/load",
+       0x1e, "door lock",
+       0x37, "read defect data",
+       -1, NULL,
+};
+
+/*
+ *     Module Loading/Unloading and Autoconfiguration Routines
+ */
+
+/*
+ * Device driver ops vector - cb_ops(9s) structure
+ * Device switch table fields (equivalent to the old 4.x cdevsw and bdevsw).
+ * Unsupported entry points (e.g. for xxprint() and xxdump()) are set to
+ * nodev, except for the poll routine, which is set to nochpoll(), a
+ * routine that returns ENXIO.
+ *
+ * Note: This uses ddi_prop_op for the prop_op(9e) routine. If your device
+ * has its own properties, you should implement a sst_prop_op() routine
+ * to manage them.
+ */
+static struct cb_ops sst_cb_ops = {
+       sst_open,               /* b/c open */
+       sst_close,              /* b/c close */
+       sst_strategy,           /* b strategy */
+       nodev,                  /* b print */
+       nodev,                  /* b dump */
+       sst_read,               /* c read */
+       sst_write,              /* c write */
+       sst_ioctl,              /* c ioctl */
+       nodev,                  /* c devmap */
+       nodev,                  /* c mmap */
+       nodev,                  /* c segmap */
+       nochpoll,               /* c poll */
+       ddi_prop_op,            /* cb_prop_op */
+       0,                      /* streamtab  */
+       D_MP | D_NEW,           /* Driver compatibility flag */
+       CB_REV,                 /* cb_ops revision number */
+       sst_aread,              /* c aread */
+       sst_awrite              /* c awrite */
+};
+
+
+/*
+ * dev_ops(9S) structure, defined in sys/devops.h.
+ * Device Operations table, for autoconfiguration
+ *
+ * Note: If you replace the sst_detach entry here with "nulldev", it
+ * implies that the detach is always successful. We need a real detach to
+ * free the sense packet and the unit structure. If you don't want the
+ * driver to ever be unloaded, replace the sst_detach entry with "nodev"
+ * (which always fails).
+ */
+static int sst_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
+               void **result);
+static int sst_probe(dev_info_t *dip);
+static int sst_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
+static int sst_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
+static int sst_power(dev_info_t *dip, int component, int level);
+
+static int sst_doattach(dev_info_t *dip);
+static int sst_dodetach(dev_info_t *dip);
+
+static struct dev_ops sst_ops = {
+       DEVO_REV,               /* devo_rev, */
+       0,                      /* refcnt  */
+       sst_info,               /* info */
+       nulldev,                /* identify */
+       sst_probe,              /* probe */
+       sst_attach,             /* attach */
+       sst_detach,             /* detach */
+       nodev,                  /* reset */
+       &sst_cb_ops,            /* driver operations */
+       (struct bus_ops *)0,    /* bus operations */
+       sst_power               /* power */
+};
+
+/*
+ * Module Loading and Unloading
+ * See modctl.h for external structure definitions.
+ */
+
+static struct modldrv modldrv = {
+       &mod_driverops,                 /* Type of module (driver). */
+       "SCSI Simple Target Driver Version 1.23",  /* Description */
+       &sst_ops,                       /* driver ops */
+};
+
+static struct modlinkage modlinkage = {
+       MODREV_1, (void *)&modldrv, NULL
+};
+
+/*
+ * Tell the system that we depend on the general scsi support routines,
+ * i.e the scsi "misc" module must be loaded
+ */
+char _depends_on[] = "misc/scsi";
+
+/*
+ * _init(9E) - module Installation
+ *
+ * Install the driver and "pre-allocate" space for INIT_UNITS units,
+ * i.e. instances of the driver.
+ */
+int
+_init(void)
+{
+       int e;
+
+       if ((e = ddi_soft_state_init(&sst_state,
+           sizeof (struct scsi_target), 0)) != 0) {
+               SST_LOG(0, SST_CE_DEBUG2,
+                       "_init, ddi_soft_state_init failed: 0x%x\n", e);
+               return (e);
+       }
+
+       if ((e = mod_install(&modlinkage)) != 0) {
+               SST_LOG(0, SST_CE_DEBUG2,
+                               "_init, mod_install failed: 0x%x\n", e);
+               ddi_soft_state_fini(&sst_state);
+       }
+
+       SST_LOG(0, SST_CE_DEBUG2, "_init succeeded\n");
+       return (e);
+}
+
+
+/*
+ * _fini(9E) - module removal
+ */
+int
+_fini(void)
+{
+       int e;
+
+       if ((e = mod_remove(&modlinkage)) != 0) {
+               SST_LOG(0, SST_CE_DEBUG1,
+                   "_fini mod_remove failed, 0x%x\n", e);
+               return (e);
+       }
+
+       ddi_soft_state_fini(&sst_state);
+
+       SST_LOG(0, SST_CE_DEBUG2, "_fini succeeded\n");
+       return (e);
+}
+
+/*
+ * _info(9E) - return module info
+ */
+int
+_info(struct modinfo *modinfop)
+{
+       SST_LOG(0, SST_CE_DEBUG2, "_info\n");
+       return (mod_info(&modlinkage, modinfop));
+}
+
+/*
+ * Autoconfiguration Routines
+ */
+
+/*
+ * probe(9e)
+ *
+ * Check that we're talking to the right device on the SCSI bus.
+ * Calls scsi_probe(9f) to see if there's a device at our target id.
+ * If there is, scsi_probe will fill in the sd_inq struct (in the devp
+ * scsi device struct) with the inquiry data. Validate the data here,
+ * allocate a request sense packet, and start filling in the private data
+ * structure.
+ *
+ * Probe should be stateless, ie it should have no side-effects. Just
+ * check that we have the right device, don't set up any data or
+ * initialize the device here.  Also, it's a Sun convention to probe
+ * quietly; send messages to the log file only, not to the console.
+ *
+ * The host adapter driver sets up the scsi_device structure and puts
+ * it into the dev_info structure with ddi_set_driver_private().
+ *
+ * No need to allow for probing/attaching in the open() routine because
+ * of the loadability - the first reference to the device will auto-load
+ * it, i.e. will call this routine.
+ */
+
+#define        VIDSZ           8       /* Vendor Id length in Inquiry Data */
+#define        PIDSZ           16      /* Product Id length in Inquiry Data */
+
+static int
+sst_probe(dev_info_t *dip)
+{
+       register struct scsi_device *devp;
+       int     err, rval = DDI_PROBE_FAILURE;
+       int     tgt, lun;
+       char    vpid[VIDSZ+PIDSZ+1];
+
+       devp = (struct scsi_device *)ddi_get_driver_private(dip);
+       tgt = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+               "target", -1);
+       lun = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
+               "lun", -1);
+
+       SST_LOG(devp, SST_CE_DEBUG2, "sst_probe: target %d, lun %d\n",
+           tgt, lun);
+
+       /*
+        * Call the routine scsi_probe to do some of the dirty work.
+        * This routine uses the SCSI Inquiry command to  test for the
+        * presence of the device. If it's successful, it will fill in
+        * the sd_inq field in the scsi_device structure.
+        */
+       switch (err = scsi_probe(devp, SLEEP_FUNC)) {
+       case SCSIPROBE_NORESP:
+               sst_log(devp, CE_CONT, "No response from target %d, lun %d\n",
+                   tgt, lun);
+               rval = DDI_PROBE_FAILURE;
+               break;
+
+       case SCSIPROBE_NONCCS:
+       case SCSIPROBE_NOMEM:
+       case SCSIPROBE_FAILURE:
+       default:
+               SST_LOG(devp, SST_CE_DEBUG1,
+                   "sst_probe: scsi_slave failed, 0x%x\n", err);
+               rval = DDI_PROBE_FAILURE;
+               break;
+
+       case SCSIPROBE_EXISTS:
+               /*
+                * Inquiry succeeded, devp->sd_inq is now filled in
+                * Note: Check inq_dtype, inq_vid, inq_pid and any other
+                *       fields to make sure the target/unit is what's
+                *       expected (sd_inq is a struct scsi_inquiry,
+                *       defined in scsi/generic/inquiry.h).
+                * Note: Put device-specific checking into the appropriate
+                *       case statement, and delete the rest.
+                * Note: The DTYPE_* defines are from <scsi/generic/inquiry.h>,
+                *       this is the full list as of "now", check it for new
+                *       types.
+                */
+               switch (devp->sd_inq->inq_dtype) {
+               case DTYPE_PROCESSOR:
+               case DTYPE_OPTICAL:
+               case DTYPE_DIRECT:
+               case DTYPE_SEQUENTIAL:
+               case DTYPE_PRINTER:
+               case DTYPE_WORM:
+               case DTYPE_RODIRECT:
+               case DTYPE_SCANNER:
+               case DTYPE_CHANGER:
+               case DTYPE_COMM:
+                       /*
+                        * Print what was found on the console. For your
+                        * device, you should send the 'found' message to
+                        * the system log file only, by inserting an
+                        * exclamation point, "!", as the first character of
+                        * the message - see cmn_err(9f).
+                        */
+                       sst_log(devp, CE_CONT,
+                           "found %s device at tgt%d, lun%d\n",
+                           scsi_dname((int)devp->sd_inq->inq_dtype), tgt, lun);
+                       bcopy(devp->sd_inq->inq_vid, vpid, VIDSZ);
+                       bcopy(devp->sd_inq->inq_pid, vpid+VIDSZ, PIDSZ);
+                       vpid[VIDSZ+PIDSZ] = 0;
+                       sst_log(devp, CE_CONT, "Vendor/Product ID = %s\n",
+                           vpid);
+                       rval = DDI_PROBE_SUCCESS;
+                       break;
+
+               case DTYPE_NOTPRESENT:
+                       sst_log(devp, CE_NOTE,
+                           "Target reports no device present\n");
+                       rval = DDI_PROBE_FAILURE;
+                       break;
+
+               default:
+                       sst_log(devp, CE_NOTE,
+                           "Unrecognized device type: 0x%x\n",
+                           devp->sd_inq->inq_dtype);
+                       rval = DDI_PROBE_FAILURE;
+                       break;
+               }
+       }
+
+       /*
+        * scsi_unprobe() must be called even if scsi_probe() failed
+        */
+       scsi_unprobe(devp);
+
+       return (rval);
+}
+
+
+
+/*
+ * Attach(9E)
+ */
+
+static int
+sst_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
+{
+       int                     instance;
+       struct scsi_target      *targ;
+       struct scsi_device      *devp;
+
+       switch (cmd) {
+       case DDI_ATTACH:
+               return (sst_doattach(dip));
+
+       case DDI_RESUME:
+               /*
+                * Suspend/Resume
+                *
+                * When the driver suspended, there were no
+                * outstanding cmds and therefore we only need to
+                * reset the suspended flag and do a cv_broadcast
+                * on the suspend_cv to wake up any blocked
+                * threads
+                */
+               instance = ddi_get_instance(dip);
+               targ = ddi_get_soft_state(sst_state, instance);
+               if (targ == NULL)
+                       return (DDI_FAILURE);
+               mutex_enter(SST_MUTEX(targ));
+               targ->targ_suspended = 0;
+
+               /* wake up threads blocked in sst_strategy */
+               cv_broadcast(&targ->targ_suspend_cv);
+
+               mutex_exit(SST_MUTEX(targ));
+
+               return (DDI_SUCCESS);
+
+       case DDI_PM_RESUME:
+               /*
+                * Power Management suspend
+                *
+                * Sinc we have no h/w state to restore, the code to
+                * handle DDI_PM_RESUME is similar to DDI_RESUME,
+                * except the driver uses the targ_pm_suspend flag.
+                */
+               instance = ddi_get_instance(dip);
+               targ = ddi_get_soft_state(sst_state, instance);
+               if (targ == NULL)
+                       return (DDI_FAILURE);
+               mutex_enter(SST_MUTEX(targ));
+
+               targ->targ_pm_suspended = 0;
+               cv_broadcast(&targ->targ_suspend_cv);
+
+               mutex_exit(SST_MUTEX(targ));
+
+               return (DDI_SUCCESS);
+
+       default:
+               SST_LOG(0, SST_CE_DEBUG1,
+                       "sst_attach: unsupported cmd 0x%x\n", cmd);
+               return (DDI_FAILURE);
+       }
+}
+
+
+/*
+ * Attach(9E) - DDI_ATTACH handling
+ *
+ *     - create minor device nodes
+ *     - initialize per-instance mutex's & condition variables
+ *     - device-specific initialization (e.g. read disk label)
+ */
+static int
+sst_doattach(dev_info_t *dip)
+{
+       int                     instance;
+       struct  scsi_pkt        *rqpkt;
+       struct scsi_target      *targ;
+       struct scsi_device      *devp;
+       struct buf              *bp;
+
+       instance = ddi_get_instance(dip);
+       devp = (struct scsi_device *)ddi_get_driver_private(dip);
+       SST_LOG(devp, SST_CE_DEBUG2, "sst_attach: instance %d\n", instance);
+
+       /*
+        * Re-probe the device to get the Inquiry data; it's used
+        * elsewhere in the driver. The Inquiry data was validated in
+        * sst_probe so there's no need to look at it again here.
+        */
+       if (scsi_probe(devp, SLEEP_FUNC) != SCSIPROBE_EXISTS) {
+               SST_LOG(0, SST_CE_DEBUG1, "sst_attach: re-probe failed\n");
+               scsi_unprobe(devp);
+               return (DDI_FAILURE);
+       }
+
+       if (ddi_soft_state_zalloc(sst_state, instance) != DDI_SUCCESS) {
+               scsi_unprobe(devp);
+               return (DDI_FAILURE);
+       }
+
+       targ = ddi_get_soft_state(sst_state, instance);
+       devp->sd_private = (opaque_t)targ;
+
+       targ->targ_sbufp = getrbuf(KM_SLEEP);
+       if (targ->targ_sbufp == NULL) {
+               goto error;
+       }
+
+       targ->targ_devp = devp;
+
+       /*
+        * Set auto-rqsense, per-target; record whether it's allowed
+        * in targ_arq
+        */
+       targ->targ_arq = (scsi_ifsetcap(ROUTE(targ),
+           "auto-rqsense", 1, 1) == 1) ? 1 : 0;
+       SST_LOG(devp, SST_CE_DEBUG2, "sst_attach: Auto Sensing %s\n",
+           targ->targ_arq ? "enabled" : "disabled");
+
+       if (!targ->targ_arq) {
+               /*
+                * Allocate a Request Sense packet
+                */
+               bp = scsi_alloc_consistent_buf(&devp->sd_address, NULL,
+                   SENSE_LENGTH, B_READ, SLEEP_FUNC, NULL);
+               if (!bp) {
+                       goto error;
+               }
+
+               rqpkt = scsi_init_pkt(&devp->sd_address, NULL, bp, CDB_GROUP0,
+                   targ->targ_arq ? sizeof (struct scsi_arq_status) : 1,
+                   sizeof (struct sst_private),
+                   PKT_CONSISTENT, SLEEP_FUNC, NULL);
+               if (!rqpkt) {
+                       goto error;
+               }
+               devp->sd_sense = (struct scsi_extended_sense *)bp->b_un.b_addr;
+
+               (void) scsi_setup_cdb((union scsi_cdb *)rqpkt->pkt_cdbp,
+                       SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0);
+
+               rqpkt->pkt_comp = sst_callback;
+               rqpkt->pkt_time = sst_io_time;
+               rqpkt->pkt_flags |= FLAG_SENSING;
+               targ->targ_rqs = rqpkt;
+               targ->targ_rqbp = bp;
+       }
+
+       /*
+        * Create the minor node(s), see the man page
+        * for ddi_create_minor_node(9f).
+        * The 2nd parameter is the minor node name; drvconfig(1M)
+        * appends it to the /devices entry, after the colon.
+        * The 4th parameter ('instance') is the actual minor number,
+        * put into the /devices entry's inode and passed to the driver.
+        * The 5th parameter ("sample_driver") is the node type; it's used
+        * by devlinks to match an entry in /etc/devlink.tab to create
+        * the link from /dev to /devices. The #defines are in <sys/sunddi.h>.
+        */
+       if (ddi_create_minor_node(dip, "character", S_IFCHR, instance,
+           "sample_driver", 0) == DDI_FAILURE) {
+               SST_LOG(0, SST_CE_DEBUG1, "Create Minor Failed\n");
+               goto error;
+       }
+
+       /*
+        * Initialize power management bookkeeping.
+        */
+       if (pm_create_components(dip, 1) == DDI_SUCCESS) {
+               if (pm_idle_component(dip, 0) == DDI_FAILURE) {
+                       SST_LOG(devp, SST_CE_DEBUG1,
+                               "pm_idle_component() failed\n");
+                       goto error;
+               }
+               pm_set_normal_power(dip, 0, 1);
+               targ->targ_power_level = 1;
+       } else {
+               SST_LOG(devp, SST_CE_DEBUG1,
+                   "pm_create_component() failed\n");
+               ddi_remove_minor_node(dip, NULL);
+               goto error;
+       }
+
+       /*
+        * Since this driver manages devices with "remote" hardware,
+        * i.e. the devices themselves have no "reg" properties,
+        * the SUSPEND/RESUME commands in detach/attach will not be
+        * called by the power management framework unless we request
+        * it by creating a "pm-hardware-state" property and setting it
+        * to value "needs-suspend-resume".
+        */
+       if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
+           "pm-hardware-state", "needs-suspend-resume") !=
+                       DDI_PROP_SUCCESS) {
+               SST_LOG(devp, SST_CE_DEBUG1,
+                   "ddi_prop_update(\"pm-hardware-state\") failed\n");
+               pm_destroy_components(dip);
+               ddi_remove_minor_node(dip, NULL);
+               goto error;
+       }
+
+       /*
+        * Initialize the condition variables.
+        * Note: We don't need to initialize the mutex (SST_MUTEX)
+        *       because it's actually devp->sd_mutex (in the struct
+        *       scsi_device) and is initialized by our parent, the
+        *       host adapter driver.
+        * Note: We don't really need targ_sbuf_cv, we could just wait
+        *       for targ_pkt_cv instead, but it's clearer this way.
+        */
+       cv_init(&targ->targ_sbuf_cv, "targ_sbuf_cv", CV_DRIVER, NULL);
+       cv_init(&targ->targ_pkt_cv, "targ_pkt_cv", CV_DRIVER, NULL);
+       cv_init(&targ->targ_suspend_cv, "targ_suspend_cv", CV_DRIVER,
+                                                       NULL);
+
+       /*
+        * Note: Do any other pre-open target initialization here,
+        *       e.g. read/verify the disk label for a fixed-disk drive.
+        */
+
+       ddi_report_dev(dip);
+       SST_LOG(devp, SST_CE_DEBUG2, "Attached sst driver\n");
+       targ->targ_state = SST_STATE_CLOSED;
+       return (DDI_SUCCESS);
+
+error:
+       if (bp) {
+               scsi_free_consistent_buf(bp);
+       }
+       if (rqpkt) {
+               scsi_destroy_pkt(rqpkt);
+       }
+       if (targ->targ_sbufp) {
+               freerbuf(targ->targ_sbufp);
+       }
+       ddi_soft_state_free(sst_state, instance);
+       devp->sd_private = (opaque_t)0;
+       devp->sd_sense = (struct scsi_extended_sense *)0;
+       scsi_unprobe(devp);
+       return (DDI_FAILURE);
+}
+
+
+/*
+ * Detach(9E)
+ */
+static int
+sst_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
+{
+       int                     instance;
+       struct scsi_device      *devp;
+       struct scsi_target      *targ;
+
+       switch (cmd) {
+
+       case DDI_DETACH:
+               return (sst_dodetach(dip));
+
+       case DDI_SUSPEND:
+               /*
+                * Suspend/Resume
+                *
+                * To process DDI_SUSPEND, we must do the following:
+                *
+                *      - wait until outstanding operations complete
+                *      - block new operations
+                *      - cancel pending timeouts
+                *      - save h/w state
+                *
+                * We don't have any h/w state in this driver, so
+                * all we really need to do is to wait for any
+                * outstanding requests to complete.  Once completed,
+                * we will have no pending timeouts either.
+                */
+               instance = ddi_get_instance(dip);
+               targ = ddi_get_soft_state(sst_state, instance);
+               if (targ == NULL) {
+                       return (DDI_FAILURE);
+               }
+
+               mutex_enter(SST_MUTEX(targ));
+               targ->targ_suspended = 1;
+
+               /*
+                * Wait here till outstanding operations complete
+                */
+               while (targ->targ_pkt_busy) {
+                       cv_wait(&targ->targ_pkt_cv, SST_MUTEX(targ));
+               }
+
+               mutex_exit(SST_MUTEX(targ));
+               return (DDI_SUCCESS);
+
+       case DDI_PM_SUSPEND:
+               /*
+                * Power Management suspend
+                *
+                * To process DDI_PM_SUSPEND, we must do the following:
+                *
+                *      - if busy, fail DDI_PM_SUSPEND
+                *      - save h/w state
+                *      - cancel pending timeouts
+                *
+                * Since we have no h/w state in this driver, we
+                * only have to check our current state.  Once idle,
+                * we have no pending timeouts.
+                */
+               instance = ddi_get_instance(dip);
+               targ = ddi_get_soft_state(sst_state, instance);
+               if (targ == NULL) {
+                       return (DDI_FAILURE);
+               }
+
+               mutex_enter(SST_MUTEX(targ));
+               ASSERT(targ->targ_suspended == 0);
+
+               /*
+                * If we have outstanding operations, fail the
+                * DDI_PM_SUSPEND.  The PM framework will retry after
+                * the device has been idle for its threshold time.
+                */
+               if (targ->targ_pkt_busy) {
+                       mutex_exit(SST_MUTEX(targ));
+                       return (DDI_FAILURE);
+               }
+
+               targ->targ_pm_suspended = 1;
+
+               mutex_exit(SST_MUTEX(targ));
+               return (DDI_SUCCESS);
+
+
+       default:
+               SST_LOG(0, SST_CE_DEBUG1,
+                       "sst_detach: bad cmd 0x%x\n", cmd);
+               return (DDI_FAILURE);
+       }
+}
+
+/*
+ * detach(9E) DDI_DETACH handling
+ *
+ * Free resources allocated in sst_attach
+ * Note: If you implement a timeout routine in this driver, cancel it
+ *      here. Note that scsi_init_pkt is called with SLEEP_FUNC, so it
+ *      will wait for resources if none are available. Changing it to
+ *      a callback constitutes a timeout; however this detach routine
+ *      will be called only if the driver is not open, and there should be
+ *      no outstanding scsi_init_pkt's if we're closed.
+ */
+static int
+sst_dodetach(dev_info_t *dip)
+{
+       int                     instance;
+       struct scsi_device      *devp;
+       struct scsi_target      *targ;
+
+       devp = (struct scsi_device *)ddi_get_driver_private(dip);
+       instance = ddi_get_instance(dip);
+       SST_LOG(devp, SST_CE_DEBUG2, "sst_detach: unit %d\n", instance);
+
+       if ((targ = ddi_get_soft_state(sst_state, instance)) == NULL) {
+               SST_LOG(devp, CE_WARN, "No Target Struct for sst%d\n",
+                   instance);
+               return (DDI_SUCCESS);
+       }
+
+       /*
+        * Note: Do unit-specific detaching here; e.g. shut down the device
+        */
+
+       /*
+        * Remove other data structures allocated in sst_attach()
+        */
+       cv_destroy(&targ->targ_sbuf_cv);
+       cv_destroy(&targ->targ_pkt_cv);
+       cv_destroy(&targ->targ_suspend_cv);
+
+       if (targ->targ_rqbp) {
+               scsi_free_consistent_buf(targ->targ_rqbp);
+       }
+       if (targ->targ_rqs) {
+               scsi_destroy_pkt(targ->targ_rqs);
+       }
+       if (targ->targ_sbufp) {
+               freerbuf(targ->targ_sbufp);
+       }
+       pm_destroy_components(dip);
+       ddi_soft_state_free(sst_state, instance);
+       devp->sd_private = (opaque_t)0;
+       devp->sd_sense = (struct scsi_extended_sense *)0;
+       ddi_remove_minor_node(dip, NULL);
+       scsi_unprobe(devp);
+       return (DDI_SUCCESS);
+}
+
+/*
+ * Power(9E)
+ *
+ * The system calls power(9E) either directly or as a result of
+ * ddi_dev_is_needed(9F) when the system determines that a
+ * component's current power level needs to be changed.
+ *
+ * Since we don't control any h/w with this driver, this code
+ * only serves as a place-holder for a real power(9E) implementation
+ * when the driver is adapted for a real device.
+ */
+static int
+sst_power(dev_info_t *dip, int component, int level)
+{
+       int                     instance;
+       struct scsi_device      *devp;
+       struct scsi_target      *targ;
+
+       devp = (struct scsi_device *)ddi_get_driver_private(dip);
+       instance = ddi_get_instance(dip);
+       SST_LOG(devp, SST_CE_DEBUG2, "sst_detach: unit %d\n", instance);
+
+       if ((targ = ddi_get_soft_state(sst_state, instance)) == NULL) {
+               SST_LOG(devp, CE_WARN, "No Target Struct for sst%d\n",
+                   instance);
+               return (DDI_FAILURE);
+       }
+
+       mutex_enter(SST_MUTEX(targ));
+
+       if (targ->targ_power_level == level) {
+               mutex_exit(SST_MUTEX(targ));
+               return (DDI_SUCCESS);
+       }
+
+       /*
+        * Set device's power level to 'level'
+        */
+       SST_LOG(devp, SST_CE_DEBUG2, "sst_power: %d -> %d\n",
+               instance, targ->targ_power_level, level);
+       targ->targ_power_level = level;
+
+       mutex_exit(SST_MUTEX(targ));
+       return (DDI_SUCCESS);
+}
+
+
+/*
+ * Entry Points
+ */
+
+
+/*
+ * open(9e)
+ *
+ * Called for each open(2) call on the device.
+ * Make sure the device is present and correct. Do any initialization that's
+ * needed (start it up, load media, etc).
+ * Note: Credp can be used to restrict access to root, by calling drv_priv(9f);
+ *      see also cred(9s).
+ *      Flag shows the access mode (read/write). Check it if the device is
+ *      read or write only, or has modes where this is relevant.
+ *      Otyp is an open type flag, see open.h.
+ *
+ * WARNING: Unfortunately there is a bug in SunOS 5.0 that affects driver
+ * open(). The file's reference count is incremented before the driver's
+ * open is called. This means that if another process closes (last close)
+ * the device while we're in the open routine, the close routine will not
+ * be called. If the open then fails (e.g. it's an exclusive open device),
+ * the file's ref count is decremented again, but the device is now in an
+ * inconsistent state - the driver thinks it's open (close was never called),
+ * but it's really closed. If it is an exclusive open device, it's now
+ * unusable. This is a particular problem if you want to block in the open
+ * routine until someone closes the device - close will never be called!
+ */
+/*ARGSUSED*/
+static int
+sst_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
+{
+       register dev_t                  dev = *dev_p;
+       register struct scsi_target     *targ;
+
+       SST_LOG(0, SST_CE_DEBUG2, "sst_open\n");
+
+       /*
+        * Test the open type flag
+        */
+       if (otyp != OTYP_CHR) {
+               SST_LOG(0, SST_CE_DEBUG1,
+                   "Unsupported open type %d\n", otyp);
+               return (EINVAL);
+       }
+
+       targ = ddi_get_soft_state(sst_state, getminor(dev));
+       if (targ == NULL) {
+               return (ENXIO);         /* invalid minor number */
+       }
+
+       /*
+        * This is an exclusive open device; fail if it's not closed.
+        * Otherwise, set the state to open - this will lock out any
+        * other access attempts. We need the mutex here because the
+        * state must not change between the test for closed and the
+        * set to open.
+        * Note With an exclusive open device, we know that no one else
+        *      will access our data structures so strictly mutexes are
+        *      not required. However since this is an example driver, and
+        *      you may want shared access, the rest of the driver is
+        *      coded with mutexes.
+        * Note If you need shared access, it's more complex. See bst.c
+        */
+       /* SST_MUTEX(targ) returns sd_mutex in the scsi_device struct */
+       mutex_enter(SST_MUTEX(targ));           /* LOCK the targ data struct */
+       if (targ->targ_state != SST_STATE_CLOSED) {
+               mutex_exit(SST_MUTEX(targ));
+               return (EBUSY);
+       }
+       targ->targ_state = SST_STATE_OPEN;      /* lock out other accesses */
+       mutex_exit(SST_MUTEX(targ));            /* UNLOCK targ data struct */
+
+       /*LINTED*/
+       _NOTE(NO_COMPETING_THREADS_NOW);
+
+       /*
+        * Test to make sure unit still is powered on and is ready
+        * by sending the SCSI Test Unit Ready command.
+        *
+        * If this is, for instance, a CD-ROM, we may get an error on the
+        * first TUR if the disk has never been accessed (a Check Condition
+        * with extended sense data to tell us why) so do one sst_unit_ready
+        * and ignore the result.
+        */
+
+/* Makes no sense for chg-scsi, test unit ready is done by chg-scsi */
+/*
+
+       (void) sst_unit_ready(dev);
+
+       if (sst_unit_ready(dev) == 0) {
+               SST_LOG(0, SST_CE_DEBUG1, "sst%d_open: not ready\n",
+                   getminor(dev));
+               targ->targ_state = SST_STATE_CLOSED;
+*/
+               /*LINTED*/
+/*
+               _NOTE(COMPETING_THREADS_NOW);
+
+               return (EIO);
+       }
+*/
+       /*
+        * Do any other initalization work here, e.g. send
+        * Mode Sense/Select commands to get the target in the
+        * right state.
+        */
+       /*LINTED*/
+       _NOTE(COMPETING_THREADS_NOW);
+
+       return (0);
+}
+
+
+/*
+ * close(9e)
+ * Called on final close only, i.e. the last close(2) call.
+ * Shut down the device, and mark it closed in the unit structure.
+ */
+/*ARGSUSED*/
+static int
+sst_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
+{
+       register struct scsi_target     *targ;
+
+       SST_LOG(0, SST_CE_DEBUG2, "sst_close\n");
+
+       targ = ddi_get_soft_state(sst_state, getminor(dev));
+       if (targ == NULL) {
+               return (ENXIO);
+       }
+
+       /*LINTED*/
+       _NOTE(NO_COMPETING_THREADS_NOW);
+
+       /*
+        * Note: Close processing here, eg rewind if it's a tape;
+        *       mark offline if removable media, etc.
+        * WARNING: Since this is an exclusive open device, other
+        *      accesses will be locked out until the state is set
+        *      to closed. If you make the device shareable, you
+        *      need to cope with the open routine being called while
+        *      we're in the close routine, and vice-versa. You could
+        *      serialize open/close calls with a semaphore or with
+        *      a condition variable. See bst.c.
+        */
+
+       targ->targ_state = SST_STATE_CLOSED;
+
+       /*LINTED*/
+       _NOTE(COMPETING_THREADS_NOW);
+
+       return (0);
+}
+
+
+/*
+ * getinfo(9E)
+ *
+ * Device Configuration Routine
+ * link instance number (unit) with dev_info structure
+ */
+/*ARGSUSED*/
+static int
+sst_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
+{
+       dev_t                   dev;
+       struct scsi_target      *targ;
+       int                     instance, error;
+
+       SST_LOG(0, SST_CE_DEBUG2, "sst_info\n");
+
+       switch (infocmd) {
+       case DDI_INFO_DEVT2DEVINFO:
+               dev = (dev_t)arg;
+               instance = getminor(dev);
+               targ = ddi_get_soft_state(sst_state, instance);
+               if (targ == NULL)
+                       return (DDI_FAILURE);
+               *result = (void *) targ->targ_devp->sd_dev;
+               error = DDI_SUCCESS;
+               break;
+       case DDI_INFO_DEVT2INSTANCE:
+               *result = (void *)getminor((dev_t)arg);
+               error = DDI_SUCCESS;
+               break;
+       default:
+               error = DDI_FAILURE;
+       }
+       return (error);
+}
+
+
+/*
+ * read(9E)
+ *
+ * Character (raw) read and write routines, called via read(2) and
+ * write(2). These routines perform "raw" (i.e. unbuffered) i/o.
+ * Just and call strategy via physio. Physio(9f) will take care of
+ * address mapping and locking, and will split the transfer if ncessary,
+ * based on minphys, possibly calling the strategy routine multiple times.
+ */
+/* ARGSUSED2 */
+static int
+sst_read(dev_t dev, struct uio *uio, cred_t *cred_p)
+{
+       SST_LOG(0, SST_CE_DEBUG2, "Read\n");
+       return (physio(sst_strategy, (struct buf *)0, dev, B_READ,
+           minphys, uio));
+}
+
+/*
+ * write(9E)
+ */
+/* ARGSUSED2 */
+static int
+sst_write(dev_t dev, struct uio *uio, cred_t *cred_p)
+{
+       SST_LOG(0, SST_CE_DEBUG2, "Write\n");
+       return (physio(sst_strategy, (struct buf *)0, dev, B_WRITE,
+           minphys, uio));
+}
+
+
+/*
+ * aread(9E) - asynchronous read
+ */
+/*ARGSUSED2*/
+static int
+sst_aread(dev_t dev, struct aio_req *aio, cred_t *credp)
+{
+       SST_LOG(0, SST_CE_DEBUG2, "aread\n");
+       return (aphysio(sst_strategy, anocancel, dev, B_READ,
+           minphys, aio));
+}
+
+/*
+ * awrite(9E) - asynchronous write
+ */
+/*ARGSUSED2*/
+static int
+sst_awrite(dev_t dev, struct aio_req *aio, cred_t *credp)
+{
+       SST_LOG(0, SST_CE_DEBUG2, "awrite\n");
+       return (aphysio(sst_strategy, anocancel, dev, B_WRITE,
+           minphys, aio));
+}
+
+
+/*
+ * strategy(9E)
+ *
+ * Main routine for commands to the device. since this is a character
+ * device, this routine is called only from the read/write routines above,
+ * and sst_ioctl_cmd for the pass through ioctl (USCSICMD).
+ * The cv_wait prevents this routine from being called simultaneously by
+ * two threads.
+ */
+static int
+sst_strategy(struct buf *bp)
+{
+       struct scsi_target      *targ;
+
+       targ = ddi_get_soft_state(sst_state, getminor(bp->b_edev));
+       if (targ == NULL) {
+               bp->b_resid = bp->b_bcount;
+               bioerror(bp, ENXIO);
+               biodone(bp);
+               return (0);
+       }
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_strategy\n");
+
+       /*
+        * Mark component busy so we won't get powered down
+        * while trying to resume.
+        */
+       if (pm_busy_component(SST_DEVINFO(targ), 0) != DDI_SUCCESS) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                   "pm_busy_component() failed\n");
+       }
+
+       mutex_enter(SST_MUTEX(targ));
+
+       /*
+        * if we are suspended, wait till we are resumed again
+        */
+       do {
+               /*
+                * Block commands while suspended via DDI_SUSPEND
+                */
+               while (targ->targ_suspended) {
+                       cv_wait(&targ->targ_suspend_cv, SST_MUTEX(targ));
+               }
+
+               /*
+                * Raise power level back to operational if needed.
+                * Since ddi_dev_is_needed() will result in our
+                * power(9E) entry point being called, we must
+                * drop the mutex.
+                */
+               if (targ->targ_power_level == 0) {
+                       mutex_exit(SST_MUTEX(targ));
+                       if (ddi_dev_is_needed(SST_DEVINFO(targ), 0, 1) !=
+                           DDI_SUCCESS) {
+                               SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                                   "ddi_dev_is_needed() failed\n");
+                       }
+                       mutex_enter(SST_MUTEX(targ));
+               }
+
+               /*
+                * We need to continue to block commands if still
+                * suspended via DDI_PM_SUSPEND.  Because we dropped
+                * the mutex to call ddi_dev_is_needed(), we may be
+                * executing in a thread that came in after the power
+                * level was raised but before attach was called with
+                * DDI_PM_RESUME.
+                */
+               while (targ->targ_pm_suspended) {
+                       cv_wait(&targ->targ_suspend_cv, SST_MUTEX(targ));
+               }
+       } while (targ->targ_suspended || (targ->targ_power_level == 0));
+
+       /*
+        * Wait for the current request to finish. We can safely release
+        * the mutex once we have the pkt, because anyone else calling
+        * strategy will wait here until we release it with a cv_signal.
+        */
+       while (targ->targ_pkt_busy) {
+               cv_wait(&targ->targ_pkt_cv, SST_MUTEX(targ));
+       }
+       targ->targ_pkt_busy =  1;               /* mark busy */
+       mutex_exit(SST_MUTEX(targ));
+
+       if (((targ->targ_pkt = sst_make_cmd(targ, bp,
+           (struct scsi_pkt *)NULL))) == NULL) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                   "Unable to create SCSI command\n");
+               bp->b_resid = bp->b_bcount;
+               bioerror(bp, EIO);
+               biodone(bp);
+               pm_idle_component(SST_DEVINFO(targ), 0);
+               return (0);
+       }
+
+       bp->b_resid = 0;
+
+       SST_DUMP_CDB(targ, targ->targ_pkt, CDB_GROUP0);
+
+       if (scsi_transport(targ->targ_pkt) != TRAN_ACCEPT) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                   "Command transport failed\n");
+               bp->b_resid = bp->b_bcount;
+               bioerror(bp, EIO);
+               biodone(bp);
+               pm_idle_component(SST_DEVINFO(targ), 0);
+       }
+
+       return (0);
+}
+
+
+/*
+ * ioctl calls.
+ * Ioctls are device specific. Three are provided here as examples:
+ * SSTIOC_READY: Send a Test Unit Ready command to the device. This fills
+ *              in the uscsi_cmd structure in the unit struct. The actual
+ *              cdb to be sent to the device is created here; the union
+ *              scsi_cdb is defined in /usr/include/sys/scsi/impl/commands.h.
+ * SST_ERRLEV: Change the error reporting level.
+ * USCSICMD:   Pass through. Send the user-supplied command to the device. Very
+ *             little checking is done - it's left up to the caller to supply
+ *             a valid cdb.
+ */
+/* ARGSUSED3 */
+static int
+sst_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
+       cred_t *cred_p, int *rval_p)
+{
+       int                     err = 0;
+       struct scsi_target      *targ;
+       struct uscsi_cmd        uscsi_cmd;
+       struct uscsi_cmd        *ucmd = &uscsi_cmd;
+       char                    cmdblk[CDB_GROUP0];
+
+#ifdef _MULTI_DATAMODEL
+       /*
+        * For use when a 32-bit app makes an ioctl into a 64-bit driver
+        */
+       struct sst_uscsi_cmd32  uscsi_cmd32;
+       struct sst_uscsi_cmd32  *ucmd32 = &uscsi_cmd32;
+       model_t                 model;
+#endif /* _MULTI_DATAMODEL */
+
+
+       targ = ddi_get_soft_state(sst_state, getminor(dev));
+       if (targ == NULL) {
+               return (ENXIO);         /* invalid minor number */
+       }
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_ioctl: cmd = 0x%x\n", cmd);
+
+       bzero(ucmd, sizeof (struct uscsi_cmd));
+
+       switch (cmd) {
+       case SSTIOC_READY:              /* Send a Test Unit Ready command */
+               ucmd->uscsi_bufaddr = 0;
+               ucmd->uscsi_buflen = 0;
+               bzero(cmdblk, CDB_GROUP0);
+               cmdblk[0] = (char)SCMD_TEST_UNIT_READY;
+               ucmd->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_WRITE;
+               ucmd->uscsi_cdb = cmdblk;
+               ucmd->uscsi_cdblen = CDB_GROUP0;
+               ucmd->uscsi_timeout = sst_io_time;
+
+               err = sst_ioctl_cmd(dev, ucmd,
+                       UIO_SYSSPACE, UIO_SYSSPACE, mode);
+               break;
+
+       case SSTIOC_ERRLEV:             /* Set the error reporting level */
+               if (ddi_copyin((void *)arg, &sst_error_reporting,
+                   sizeof (int32_t), mode)) {
+                       return (EFAULT);
+               }
+               break;
+
+       case USCSICMD:
+               /*
+                * Run a generic ucsi.h command.
+                */
+
+#if 0 /* allow non-root to do this */
+               /*
+                * Check root permissions
+                */
+               if (drv_priv(cred_p) != 0) {
+                       return (EPERM);
+               }
+#endif
+
+#ifdef _MULTI_DATAMODEL
+               switch (model = ddi_model_convert_from(mode & FMODELS)) {
+               case DDI_MODEL_ILP32:
+               {
+                       if (ddi_copyin((void *)arg, ucmd32,
+                           sizeof (*ucmd32), mode)) {
+                               return (EFAULT);
+                       }
+                       /*
+                        * Convert 32-bit ILP32 application's uscsi cmd
+                        * into 64-bit LP64 equivalent for internal use
+                        */
+                       sst_uscsi_cmd32touscsi_cmd(ucmd32, ucmd);
+                       break;
+               }
+               case DDI_MODEL_NONE:
+                       if (ddi_copyin((void *)arg, ucmd,
+                           sizeof (*ucmd), mode)) {
+                               return (EFAULT);
+                       }
+                       break;
+               }
+
+#else /* ! _MULTI_DATAMODEL */
+               if (ddi_copyin((void *)arg, ucmd,
+                   sizeof (*ucmd), mode)) {
+                       return (EFAULT);
+               }
+#endif /* _MULTI_DATAMODEL */
+
+               err = sst_ioctl_cmd(dev, ucmd,
+                       UIO_USERSPACE, UIO_USERSPACE, mode);
+
+#ifdef _MULTI_DATAMODEL
+               switch (model) {
+               case DDI_MODEL_ILP32:
+                       /*
+                        * Convert LP64 back to IPL32 before copyout
+                        */
+                       sst_uscsi_cmdtouscsi_cmd32(ucmd, ucmd32);
+
+                       if (ddi_copyout(ucmd32, (void *)arg,
+                           sizeof (*ucmd32), mode)) {
+                               return (EFAULT);
+                       }
+                       break;
+
+               case DDI_MODEL_NONE:
+                       if (ddi_copyout(ucmd, (void *)arg,
+                           sizeof (*ucmd), mode)) {
+                               return (EFAULT);
+                       }
+                       break;
+               }
+#else /* ! _MULTI_DATAMODE */
+               if (ddi_copyout(ucmd, (void *)arg,
+                   sizeof (*ucmd), mode)) {
+                       return (EFAULT);
+               }
+#endif /* _MULTI_DATAMODE */
+               break;
+
+
+       default:
+               err = ENOTTY;
+               break;
+       }
+       return (err);
+}
+
+
+/*
+ * Run a command for user (from sst_ioctl) or from someone else in the driver.
+ *
+ * cdbspace is for address space of cdb; dataspace is for address space
+ * of the buffer - user or kernel.
+ */
+static int
+sst_ioctl_cmd(dev_t dev, struct uscsi_cmd *scmd,
+    enum uio_seg cdbspace, enum uio_seg dataspace,
+    int mode)
+{
+       caddr_t                 cdb, user_cdbp;
+       int                     err, rw;
+       struct buf              *bp;
+       struct scsi_target      *targ;
+       int                     flag;
+
+       targ = ddi_get_soft_state(sst_state, getminor(dev));
+       if (targ == NULL) {
+               return (ENXIO);
+       }
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_ioctl_cmd\n");
+
+       /*
+        * The uscsi structure itself is already in kernel space (copied
+        * in by sst_ioctl, or declared there by our caller); but
+        * we need to copy in the cdb here.
+        */
+       cdb = kmem_zalloc((size_t)scmd->uscsi_cdblen, KM_SLEEP);
+       flag = (cdbspace == UIO_SYSSPACE) ? FKIOCTL : mode;
+       if (ddi_copyin(scmd->uscsi_cdb, cdb,
+           (u_int)scmd->uscsi_cdblen, flag)) {
+               kmem_free(cdb, (size_t)scmd->uscsi_cdblen);
+               return (EFAULT);
+       }
+
+       /*
+        * The cdb pointer in the structure passed by the user is pointing
+        * to user space. We've just copied the cdb into a local buffer,
+        * so point uscsi_cdb to it now. We'll restore the user's pointer
+        * at the end.
+        */
+       user_cdbp = scmd->uscsi_cdb;    /* save the user's pointer */
+       scmd->uscsi_cdb = cdb;          /* point to the local cdb buffer */
+       rw = (scmd->uscsi_flags & USCSI_READ) ? B_READ : B_WRITE;
+
+       /*
+        * Get the 'special command' buffer.
+        * First lock the targ struct; if the buffer's busy, wait for
+        * it to become free. Once we get the buffer, mark it busy to
+        * lock out other requests for it.
+        * Note cv_wait will release the mutex, allowing other parts
+        *      of the driver to acquire it.
+        * Note Once we have the special buffer, we can safely release
+        *      the mutex; the buffer is now busy and another thread will
+        *      block in the cv_wait until we release it. All the code
+        *      from here until we unset the busy flag is non-reentrant,
+        *      including the physio/strategy/start/callback/done thread.
+        */
+       mutex_enter(SST_MUTEX(targ));
+       while (targ->targ_sbuf_busy) {
+               cv_wait(&targ->targ_sbuf_cv, SST_MUTEX(targ));
+       }
+       targ->targ_sbuf_busy = 1;
+       mutex_exit(SST_MUTEX(targ));
+
+       bp = targ->targ_sbufp;
+
+       if (scmd->uscsi_buflen) {
+               /*
+                * We're sending/receiving data; create a uio structure and
+                * call physio to do the right things.
+                */
+               auto struct     iovec   aiov;
+               auto struct     uio     auio;
+               register struct uio     *uio = &auio;
+
+               bzero(&auio, sizeof (struct uio));
+               bzero(&aiov, sizeof (struct iovec));
+               aiov.iov_base = scmd->uscsi_bufaddr;
+               aiov.iov_len = scmd->uscsi_buflen;
+               uio->uio_iov = &aiov;
+
+               uio->uio_iovcnt = 1;
+               uio->uio_resid = scmd->uscsi_buflen;
+               uio->uio_segflg = dataspace;
+               uio->uio_offset = 0;
+               uio->uio_fmode = 0;
+
+               /*
+                * Let physio do the rest...
+                */
+               bp->b_private = (void *) scmd;
+               err = physio(sst_strategy, bp, dev, rw, minphys, uio);
+       } else {
+               /*
+                * No data transfer, we can call sst_strategy directly
+                */
+               bp->b_private = (void *) scmd;
+               bp->b_flags = B_BUSY | rw;
+               bp->b_edev = dev;
+               bp->b_bcount = bp->b_blkno = 0;
+               (void) sst_strategy(bp);
+               err = biowait(bp);
+       }
+
+       /*
+        * get the status block, if any, and
+        * release any resources that we had.
+        */
+       scmd->uscsi_status = 0;
+       scmd->uscsi_status = SCBP_C(targ->targ_pkt);
+
+       /*
+        * Lock the targ struct. Clearing the 'busy' flag and signalling
+        * must be made atomic.
+        */
+       mutex_enter(SST_MUTEX(targ));           /* LOCK the targ struct */
+       if (targ->targ_pkt != NULL)
+               scsi_destroy_pkt(targ->targ_pkt);
+       targ->targ_sbuf_busy = 0;
+       cv_signal(&targ->targ_sbuf_cv);         /* release the special buffer */
+       targ->targ_pkt_busy = 0;
+       cv_signal(&targ->targ_pkt_cv);          /* release the packet */
+       mutex_exit(SST_MUTEX(targ));            /* UNLOCK the targ struct */
+
+       kmem_free(scmd->uscsi_cdb, (size_t)scmd->uscsi_cdblen);
+       scmd->uscsi_cdb = user_cdbp;    /* restore the user's pointer */
+       return (err);
+}
+
+
+/*
+ * Check to see if the unit will respond to a Test Unit Ready
+ * Returns true or false
+ */
+static int
+sst_unit_ready(dev_t dev)
+{
+       auto struct uscsi_cmd scmd, *com = &scmd;
+       auto char       cmdblk[CDB_GROUP0];
+       auto int        err;
+
+       com->uscsi_bufaddr = 0;
+       com->uscsi_buflen = 0;
+       bzero(cmdblk, CDB_GROUP0);
+       cmdblk[0] = (char)SCMD_TEST_UNIT_READY;
+       com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_WRITE;
+       com->uscsi_cdb = cmdblk;
+       com->uscsi_cdblen = CDB_GROUP0;
+       com->uscsi_timeout = sst_io_time;
+
+       if (err = sst_ioctl_cmd(dev, com, UIO_SYSSPACE, UIO_SYSSPACE, 0)) {
+               SST_LOG(0, SST_CE_DEBUG1, "sst_unit_ready failed: 0x%x\n", err);
+               return (0);
+       }
+       return (1);
+}
+
+
+/*
+ * Done with a command.
+ * Start the next command and then call biodone() to tell physio or
+ * sst_ioctl_cmd that this i/o has completed.
+ *
+ */
+static void
+sst_done(struct scsi_target *targ, register struct buf *bp)
+{
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_done\n");
+
+       /*
+        * Lock the targ struct; we don't want targ_pkt to change
+        * between taking a copy of it and zeroing it.
+        */
+       mutex_enter(SST_MUTEX(targ));
+
+       /*
+        * For regular commands (i.e. not using the special buffer),
+        * free resources and clear the current request. Sst_ioctl_cmd
+        * will do its own freeing for special commands. We need the lock
+        * here because targ_pkt must not change during the operations.
+        */
+       if (bp != targ->targ_sbufp) {
+               scsi_destroy_pkt(targ->targ_pkt);
+               targ->targ_pkt_busy = 0;
+               cv_signal(&targ->targ_pkt_cv);
+       }
+
+       mutex_exit(SST_MUTEX(targ));            /* UNLOCK the targ struct */
+
+       /*
+        * Tell interested parties that the i/o is done
+        */
+       biodone(bp);
+       pm_idle_component(SST_DEVINFO(targ), 0);
+}
+
+
+/*
+ * Allocate resources for a SCSI command - call scsi_init_pkt to get
+ * a packet and allocate DVMA resources, and create the SCSI CDB.
+ *
+ * Also used to continue an in-progress packet; simply calls scsi_init_pkt
+ * to update the DMA resources to the next chunk, and re-creates the
+ * SCSI command.
+ *
+ * Note: There are differences in the DMA subsystem between the SPARC
+ *     and x86 platforms. For example, on the x86 platform, DMA uses
+ *     physical rather than virtual addresses as a result the DMA buffer
+ *     may not be contiguous.
+ *
+ *     Because of these differences, the system may not be able to fully
+ *     satisfy a DMA allocation request from the target driver with resources
+ *     attached to one packet. As a solution, the scsi_init_pkt() routine
+ *     should be called with the PKT_DMA _PARTIAL flag to allow the system
+ *     to break up the DMA request. If a single DMA allocation cannot be
+ *     done, the HBA driver sets the pkt_resid in the scsi_pkt structure
+ *     to the number of bytes of DMA resources it was able to  allocate.
+ *     The target driver needs to modify the SCSI command it places into
+ *     the packet for transport to request the proper amount of data specified
+ *     in pkt_resid. When the packet's completion routine is called, the
+ *     process is repeated again.
+ *
+ */
+static struct scsi_pkt *
+sst_make_cmd(struct scsi_target *targ, struct buf *bp, struct scsi_pkt *pkt)
+{
+       struct uscsi_cmd *scmd = (struct uscsi_cmd *)bp->b_private;
+       int                     tval, blkcnt;
+       u_int                   flags;
+       int                     pktalloc = 0;
+       struct sst_private      *sstprivp;
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+           "sst_make_cmd: block %d, count=%d\n", bp->b_blkno, bp->b_bcount);
+
+       /*
+        * If called with pkt == NULL, this is first time, and we
+        * must allocate and initialize the packet
+        */
+       if (pkt == (struct scsi_pkt *)NULL)
+               pktalloc = 1;
+
+       flags = 0;
+       blkcnt = bp->b_bcount >> DEV_BSHIFT;
+
+       if (bp != targ->targ_sbufp) {
+               /*
+                * Allocate a packet.
+                * ROUTE(targ) is shorthand for sd_address
+                * Note that if auto request sensing is enabled, we
+                * specify the status length to hold sense data if needed
+                */
+               if (pktalloc) {
+                       pkt = scsi_init_pkt(ROUTE(targ),
+                           (struct scsi_pkt *)NULL, bp,
+                           (bp->b_blkno + blkcnt > 0x1FFFFF || blkcnt > 0xFF) ?
+                               CDB_GROUP1 : CDB_GROUP0,
+                           targ->targ_arq ?
+                           sizeof (struct scsi_arq_status) : 1,
+                           sizeof (struct sst_private), PKT_DMA_PARTIAL,
+                           SLEEP_FUNC, 0);
+                       if (pkt == (struct scsi_pkt *)0) {
+                               return (NULL);
+                       }
+               } else {
+                       /*
+                        * Here we're simply calling scsi_init_pkt() for the
+                        * next section of DMA resource for the current
+                        * I/O request (in bp); we needn't worry about
+                        * the associated lengths, or possible failure,
+                        * since scsi_init_pkt() is just moving the DMA win
+                        */
+                       pkt = scsi_init_pkt(ROUTE(targ), pkt, bp, 0,
+                           targ->targ_arq ?
+                           sizeof (struct scsi_arq_status) : 1,
+                           sizeof (struct sst_private),
+                           PKT_DMA_PARTIAL, NULL_FUNC, 0);
+               }
+
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG3,
+                   "sst_make_cmd: pkt_resid: %d\n", pkt->pkt_resid);
+
+               sstprivp = (struct sst_private *)pkt->pkt_private;
+
+               if (pktalloc) {
+                       sstprivp->priv_bp = bp;
+                       sstprivp->priv_amtdone = 0;
+                       sstprivp->priv_amt = bp->b_bcount - pkt->pkt_resid;
+               }
+
+               sst_fill_cdb(pkt, targ, bp, flags);
+               pkt->pkt_flags = flags;
+               tval = sst_io_time;
+       } else {
+               /*
+                * All special command come through sst_ioctl_cmd, which
+                * uses the uscsi interface. Just need to get the CDB
+                * from scmd and plug it in. Still call scsi_setup_cdb because
+                * it fills in some of the pkt field for us. Its cdb
+                * manipulations will be overwritten by the bcopy.
+                */
+               if (scmd->uscsi_flags & USCSI_SILENT)
+                       flags |= FLAG_SILENT;
+               if (scmd->uscsi_flags & USCSI_DIAGNOSE)
+                       flags |= FLAG_DIAGNOSE;
+               if (scmd->uscsi_flags & USCSI_ISOLATE)
+                       flags |= FLAG_ISOLATE;
+               if (scmd->uscsi_flags & USCSI_NODISCON)
+                       flags |= FLAG_NODISCON;
+               if (scmd->uscsi_flags & USCSI_NOPARITY)
+                       flags |= FLAG_NOPARITY;
+
+               if (pktalloc) {
+                       pkt = scsi_init_pkt(ROUTE(targ),
+                           (struct scsi_pkt *)NULL,
+                           bp->b_bcount ? bp : 0,
+                           scmd->uscsi_cdblen,
+                           targ->targ_arq ?
+                           sizeof (struct scsi_arq_status) : 1,
+                           sizeof (struct sst_private), PKT_DMA_PARTIAL,
+                           SLEEP_FUNC, 0);
+                       if (!pkt) {
+                               return (NULL);
+                       }
+               } else {
+                       pkt = scsi_init_pkt(ROUTE(targ), pkt,
+                           bp->b_bcount ? bp : 0, 0,
+                           targ->targ_arq ?
+                           sizeof (struct scsi_arq_status) : 1,
+                           sizeof (struct sst_private),
+                           PKT_DMA_PARTIAL, NULL_FUNC, 0);
+               }
+
+               sstprivp = (struct sst_private *)pkt->pkt_private;
+               if (pktalloc) {
+                       sstprivp->priv_bp = bp;
+                       sstprivp->priv_amtdone = 0;
+                       sstprivp->priv_amt = bp->b_bcount - pkt->pkt_resid;
+               }
+
+               (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp,
+                       scmd->uscsi_cdb[0], 0, 0, 0);
+
+               bcopy(scmd->uscsi_cdb, pkt->pkt_cdbp,
+                   scmd->uscsi_cdblen);
+               tval = scmd->uscsi_timeout;
+
+               /* a timeout of 0 (ie. no timeout) is bad practice */
+               if (tval == 0) {
+                       tval = sst_io_time;
+               }
+       }
+
+       pkt->pkt_comp = sst_callback;
+       pkt->pkt_time = tval;
+
+#ifdef SST_DEBUG
+       if (sst_debug > 2) {
+               hex_print("sst_make_cmd, CDB", pkt->pkt_cdbp, 6);
+       }
+#endif SST_DEBUG
+
+       return (pkt);
+}
+
+
+/*
+ * Stuff CDB with SCSI command for current I/O request
+ */
+
+static void
+sst_fill_cdb(struct scsi_pkt *pkt, struct scsi_target *targ, struct buf *bp,
+    u_int flags)
+{
+       struct sst_private *sstprivp;
+       u_int blkno, len;
+       u_int com;
+
+       if ((scsi_options & SCSI_OPTIONS_DR) == 0)
+               flags |= FLAG_NODISCON;
+
+       sstprivp = (struct sst_private *)(pkt->pkt_private);
+
+       blkno = bp->b_blkno + (sstprivp->priv_amtdone >> DEV_BSHIFT);
+       /* use result of scsi_init_pkt() as I/O length */
+       len = sstprivp->priv_amt; /* pkt->pkt_resid; */
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG3,
+           "sst_fill_cdb: blkno %x len %x\n", blkno, len);
+       /*
+        * Note: We use the group 0 Read/Write commands here
+        *      unless the starting block number or blocks
+        *      requested is too large.
+        *      If your device needs different commands for normal
+        *      data transfer (e.g. Send/Receive, read/write buffer),
+        *      change it here.
+        */
+
+       if ((blkno + (len >> DEV_BSHIFT) > 0x1FFFFF) ||
+           ((len >> DEV_BSHIFT) > 0xFF)) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG3,
+                   "sst_make_cmd: using g1 command\n");
+               com = (bp->b_flags & B_READ) ? SCMD_READ_G1 : SCMD_WRITE_G1;
+       } else {
+               com = (bp->b_flags & B_READ) ? SCMD_READ : SCMD_WRITE;
+       }
+
+       /*
+        * Note: The CDB creation differs for sequential and
+        *       direct access devices. We do both here, but
+        *       you should need only one. For sequential access,
+        *       we assume a fixed 512 byte block size. If you
+        *       have a variable block size device, ask for the
+        *       actual number of bytes wanted, and change the last
+        *       parameter, 'fixbit' (1) to zero.
+        */
+       if (targ->targ_devp->sd_inq->inq_dtype == DTYPE_SEQUENTIAL) {
+               blkno = 0;
+       }
+
+       (void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp,
+                               com, blkno, len >> DEV_BSHIFT, 0);
+       pkt->pkt_flags = flags;
+
+       if (targ->targ_devp->sd_inq->inq_dtype == DTYPE_SEQUENTIAL) {
+               ((union scsi_cdb *)(pkt->pkt_cdbp))->t_code = 1;
+       }
+}
+
+
+/*
+ * -----------------------------------------------------------------------------
+ * Interrupt Service Routines
+ */
+
+/*
+ * Restart a command - the device was either busy or not ready
+ */
+static void
+sst_restart(caddr_t arg)
+{
+       struct scsi_target      *targ = (struct scsi_target *)arg;
+       struct scsi_pkt         *pkt;
+       struct buf              *bp;
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "sst_restart\n");
+
+       /*
+        * No need to lock the targ structure because any other threads
+        * will wait in sst_strategy for the packet.
+        */
+       pkt = targ->targ_pkt;
+       bp = ((struct sst_private *)pkt->pkt_private)->priv_bp;
+
+       if (bp) {
+               struct scsi_pkt *pkt = targ->targ_pkt;
+
+               if (pkt->pkt_flags & FLAG_SENSING) {
+                       pkt = targ->targ_rqs;
+               }
+
+               SST_DUMP_CDB(targ, targ->targ_pkt, CDB_GROUP0);
+
+               if (scsi_transport(pkt) != TRAN_ACCEPT) {
+                       bp->b_resid = bp->b_bcount;
+                       bioerror(bp, ENXIO);
+                       sst_done(targ, bp);
+               }
+       }
+}
+
+
+/*
+ * Command completion processing, called by the host adapter driver
+ * when it's done with the command.
+ * No need for mutexes in this routine - there's only one active command
+ * at a time, anyone else wanting to send a command will wait in strategy
+ * until we call sst_done.
+ */
+static void
+sst_callback(struct scsi_pkt *pkt)
+{
+       struct scsi_target      *targ;
+       struct buf              *bp;
+       int                     action;
+       struct sst_private      *sstprivp;
+
+       sstprivp = (struct sst_private *)pkt->pkt_private;
+       bp = sstprivp->priv_bp;
+       targ = ddi_get_soft_state(sst_state, getminor(bp->b_edev));
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+       "sst_callback: pkt_reason = 0x%x, pkt_flags = 0x%x, pkt_state = 0x%x\n",
+           pkt->pkt_reason, pkt->pkt_flags, pkt->pkt_state);
+
+       mutex_enter(SST_MUTEX(targ));
+
+       if (pkt->pkt_reason != CMD_CMPLT) {
+               /*
+                * The command did not complete. Retry if possible.
+                */
+               action = sst_handle_incomplete(targ);
+       } else if (targ->targ_arq && pkt->pkt_state & STATE_ARQ_DONE) {
+               /*
+                * The auto-rqsense happened, and the packet has a
+                * filled-in scsi_arq_status structure, pointed to by
+                * pkt_scbp.
+                */
+               action = sst_handle_arq(pkt, targ, bp);
+       } else if (pkt->pkt_flags & FLAG_SENSING) {
+               /*
+                * We were running a REQUEST SENSE. Decode the
+                * sense data and decide what to do next.
+                */
+               pkt = targ->targ_pkt;   /* get the pkt for the orig command */
+               pkt->pkt_flags &= ~FLAG_SENSING;
+               action = sst_handle_sense(targ, bp);
+       } else {
+               /*
+                * Command completed and we're not getting sense. Check
+                * for errors and decide what to do next.
+                */
+               action = sst_check_error(targ, bp);
+       }
+       mutex_exit(SST_MUTEX(targ));
+
+       switch (action) {
+       case QUE_SENSE:
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Getting Sense\n");
+               pkt->pkt_flags |= FLAG_SENSING;
+               ((struct sst_private *)targ->targ_rqs->pkt_private)->
+                                                               priv_bp = bp;
+               bzero(targ->targ_devp->sd_sense, SENSE_LENGTH);
+               SST_DUMP_CDB(targ, targ->targ_rqs, CDB_GROUP0);
+               if (scsi_transport(targ->targ_rqs) == TRAN_ACCEPT) {
+                       break;
+               }
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                   "Request Sense transport failed\n");
+               /*FALLTHROUGH*/
+       case COMMAND_DONE_ERROR:
+               bp->b_resid = bp->b_bcount;
+               bioerror(bp, ENXIO);
+               /*FALLTHROUGH*/
+       case COMMAND_DONE:
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Command Done\n");
+               sst_done(targ, bp);
+               break;
+
+       case QUE_COMMAND:
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Retrying Command\n");
+               SST_DUMP_CDB(targ, targ->targ_pkt, CDB_GROUP0);
+               if (scsi_transport(targ->targ_pkt) != TRAN_ACCEPT) {
+                       SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                           "Retry transport failed\n");
+                       bp->b_resid = bp->b_bcount;
+                       bioerror(bp, ENXIO);
+                       sst_done(targ, bp);
+                       return;
+               }
+               break;
+       case JUST_RETURN:
+               break;
+
+       case CONTINUE_PKT:
+               /*
+                * Back from a chunk of a split-up bp.  Do next chunk or
+                * finish up.
+                */
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Continuing packet\n");
+               (void) sst_make_cmd(targ, bp, pkt);
+               SST_DUMP_CDB(targ, pkt, CDB_GROUP0);
+               if (scsi_transport(pkt) != TRAN_ACCEPT) {
+                       SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                           "Command transport failedn");
+                       bp->b_resid = bp->b_bcount;
+                       bioerror(bp, EIO);
+                       biodone(bp);
+                       pm_idle_component(SST_DEVINFO(targ), 0);
+               }
+       }
+
+}
+
+
+/*
+ * Incomplete command handling. Figure out what to do based on
+ * how far the command did get.
+ */
+static int
+sst_handle_incomplete(struct scsi_target *targ)
+{
+       register int    rval = COMMAND_DONE_ERROR;
+       register struct scsi_pkt        *pkt = targ->targ_pkt;
+
+       if (!targ->targ_arq && pkt->pkt_flags & FLAG_SENSING) {
+               pkt = targ->targ_rqs;
+       }
+
+       /*
+        * The target may still be running the  command,
+        * so try and reset it, to get it into a known state.
+        * Note: This is forcible, there may be a more polite
+        *       method for your device.
+        */
+       if ((pkt->pkt_statistics &
+           (STAT_BUS_RESET|STAT_DEV_RESET|STAT_ABORTED)) == 0) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG1, "Aborting Command\n");
+               mutex_exit(SST_MUTEX(targ));
+               if (!(scsi_abort(ROUTE(targ), (struct scsi_pkt *)0))) {
+                       SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                           "Resetting Target\n");
+                       if (!(scsi_reset(ROUTE(targ), RESET_TARGET))) {
+                               SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                                   "Resetting SCSI Bus\n");
+                               if (!scsi_reset(ROUTE(targ), RESET_ALL)) {
+                                       sst_log(targ->targ_devp, CE_WARN,
+                                           "SCSI bus reset failed\n");
+                               }
+                               mutex_enter(SST_MUTEX(targ));
+                               return (COMMAND_DONE_ERROR);
+                       }
+               }
+               mutex_enter(SST_MUTEX(targ));
+       }
+
+       /*
+        * If we were running a request sense, try it again if possible.
+        * Some devices can handle retries, others will not.
+        */
+       if (pkt->pkt_flags & FLAG_SENSING) {
+               if (targ->targ_retry_ct++ < sst_retry_count) {
+                       rval = QUE_SENSE;
+               }
+       } else if (targ->targ_retry_ct++ < sst_retry_count) {
+               rval = QUE_COMMAND;
+       } else {
+               rval = COMMAND_DONE_ERROR;
+       }
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG1, "Cmd incomplete, %s\n",
+           (rval == COMMAND_DONE_ERROR) ? "giving up" : "retrying");
+
+       return (rval);
+}
+
+
+/*
+ * Decode sense data
+ */
+static int
+sst_handle_sense(struct scsi_target *targ, struct buf *bp)
+{
+       struct scsi_pkt *rqpkt = targ->targ_rqs;
+       register        rval = COMMAND_DONE_ERROR;
+       int             level, amt;
+
+
+       if (SCBP(rqpkt)->sts_busy) {
+               if (targ->targ_retry_ct++ < sst_retry_count) {
+                       (void) timeout(sst_restart, (caddr_t)targ,
+                           SST_BSY_TIMEOUT);
+                       rval = JUST_RETURN;
+               }
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG1, "Target Busy, %s\n",
+                   (rval == JUST_RETURN) ? "restarting" : "giving up");
+               return (rval);
+       }
+
+       if (SCBP(rqpkt)->sts_chk) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+                   "Check Condition on Request Sense!\n");
+               return (rval);
+       }
+
+       amt = SENSE_LENGTH - rqpkt->pkt_resid;
+       if ((rqpkt->pkt_state & STATE_XFERRED_DATA) == 0 || amt == 0) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "no sense data\n");
+               return (rval);
+       }
+
+       /*
+        * Now, check to see whether we got enough sense data to make any
+        * sense out if it (heh-heh).
+        */
+       if (amt < SUN_MIN_SENSE_LENGTH) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+                   "not enough sense data\n");
+               return (rval);
+       }
+
+       if (sst_debug > 2) {
+               hex_print("sst Sense Data", targ->targ_devp->sd_sense,
+                   SENSE_LENGTH);
+       }
+
+       /*
+        * Decode the sense data
+        * Note: We only looking at the sense key here. Most devices
+        *       have unique additional sense codes & qualifiers, so
+        *       it's often more useful to look at them instead.
+        *
+        */
+       switch (targ->targ_devp->sd_sense->es_key) {
+       case KEY_NOT_READY:
+               /*
+                * If we get a not-ready indication, wait a bit and
+                * try it again, unless this is a special command with
+                * the 'fail on error' (FLAG_DIAGNOSE) option set.
+                */
+               if ((bp == targ->targ_sbufp) &&
+                   (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) {
+                       rval = COMMAND_DONE_ERROR;
+                       level = SCSI_ERR_FATAL;
+               } else if (targ->targ_retry_ct++ < sst_retry_count) {
+                       (void) timeout(sst_restart, (caddr_t)targ,
+                           SST_BSY_TIMEOUT);
+                       rval = JUST_RETURN;
+                       level = SCSI_ERR_RETRYABLE;
+               } else {
+                       rval = COMMAND_DONE_ERROR;
+                       level = SCSI_ERR_FATAL;
+               }
+               break;
+
+       case KEY_ABORTED_COMMAND:
+       case KEY_UNIT_ATTENTION:
+               rval = QUE_COMMAND;
+               level = SCSI_ERR_INFO;
+               break;
+       case KEY_RECOVERABLE_ERROR:
+       case KEY_NO_SENSE:
+               rval = COMMAND_DONE;
+               level = SCSI_ERR_RECOVERED;
+               break;
+       case KEY_HARDWARE_ERROR:
+       case KEY_MEDIUM_ERROR:
+       case KEY_MISCOMPARE:
+       case KEY_VOLUME_OVERFLOW:
+       case KEY_WRITE_PROTECT:
+       case KEY_BLANK_CHECK:
+       case KEY_ILLEGAL_REQUEST:
+       default:
+               rval = COMMAND_DONE_ERROR;
+               level = SCSI_ERR_FATAL;
+               break;
+       }
+
+       /*
+        * If this was for a special command, check the options
+        */
+       if (bp == targ->targ_sbufp) {
+               if ((rval == QUE_COMMAND) &&
+                   (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) {
+                       rval = COMMAND_DONE_ERROR;
+               }
+               if (((targ->targ_pkt->pkt_flags & FLAG_SILENT) == 0) ||
+                   sst_debug) {
+                       scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst",
+                           level, bp->b_blkno, 0, sst_cmds,
+                           targ->targ_devp->sd_sense);
+               }
+       } else if ((level >= sst_error_reporting) || sst_debug) {
+               scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst",
+                   level, bp->b_blkno, 0, sst_cmds, targ->targ_devp->sd_sense);
+       }
+
+       return (rval);
+}
+
+
+#define        ARQP(pktp)      ((struct scsi_arq_status *)((pktp)->pkt_scbp))
+
+/*
+ * Decode auto-rqsense data
+ */
+static int
+sst_handle_arq(struct scsi_pkt *pktp, struct scsi_target *targ, struct buf *bp)
+{
+       int     level, amt, rval = COMMAND_DONE_ERROR;
+
+       SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Auto Request Sense done\n");
+
+       if (ARQP(pktp)->sts_rqpkt_status.sts_chk) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+                   "Check Condition on Auto Request Sense!\n");
+               return (rval);
+       }
+
+       amt = SENSE_LENGTH - ARQP(pktp)->sts_rqpkt_resid;
+       if ((ARQP(pktp)->sts_rqpkt_state & STATE_XFERRED_DATA) == 0 ||
+           amt == 0) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "no auto sense data\n");
+               return (rval);
+       }
+
+       /*
+        * Stuff the sense data pointer into sd_sense
+        */
+       targ->targ_devp->sd_sense = &(ARQP(pktp)->sts_sensedata);
+
+       /*
+        * Now, check to see whether we got enough sense data to make any
+        * sense out if it (heh-heh).
+        */
+       if (amt < SUN_MIN_SENSE_LENGTH) {
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+                   "not enough auto sense data\n");
+               return (rval);
+       }
+
+       if (sst_debug > 2) {
+               hex_print("sst Auto Sense Data",
+                   &(ARQP(pktp)->sts_sensedata), SENSE_LENGTH);
+       }
+
+       /*
+        * Decode the sense data
+        * Note: I'm only looking at the sense key here. Most devices
+        *       have unique additional sense codes & qualifiers, so
+        *       it's often more useful to look at them instead.
+        *
+        */
+       switch (ARQP(pktp)->sts_sensedata.es_key) {
+       case KEY_NOT_READY:
+               /*
+                * If we get a not-ready indication, wait a bit and
+                * try it again, unless this is a special command with
+                * the 'fail on error' (FLAG_DIAGNOSE) option set.
+                */
+               if ((bp == targ->targ_sbufp) &&
+                   (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) {
+                       rval = COMMAND_DONE_ERROR;
+                       level = SCSI_ERR_FATAL;
+               } else if (targ->targ_retry_ct++ < sst_retry_count) {
+                       (void) timeout(sst_restart, (caddr_t)targ,
+                           SST_BSY_TIMEOUT);
+                       rval = JUST_RETURN;
+                       level = SCSI_ERR_RETRYABLE;
+               } else {
+                       rval = COMMAND_DONE_ERROR;
+                       level = SCSI_ERR_FATAL;
+               }
+               break;
+
+       case KEY_ABORTED_COMMAND:
+       case KEY_UNIT_ATTENTION:
+               rval = QUE_COMMAND;
+               level = SCSI_ERR_INFO;
+               break;
+       case KEY_RECOVERABLE_ERROR:
+       case KEY_NO_SENSE:
+               rval = COMMAND_DONE;
+               level = SCSI_ERR_RECOVERED;
+               break;
+       case KEY_HARDWARE_ERROR:
+       case KEY_MEDIUM_ERROR:
+       case KEY_MISCOMPARE:
+       case KEY_VOLUME_OVERFLOW:
+       case KEY_WRITE_PROTECT:
+       case KEY_BLANK_CHECK:
+       case KEY_ILLEGAL_REQUEST:
+       default:
+               rval = COMMAND_DONE_ERROR;
+               level = SCSI_ERR_FATAL;
+               break;
+       }
+
+       /*
+        * If this was for a special command, check the options
+        */
+       if (bp == targ->targ_sbufp) {
+               if ((rval == QUE_COMMAND) &&
+                   (targ->targ_pkt->pkt_flags & FLAG_DIAGNOSE)) {
+                       rval = COMMAND_DONE_ERROR;
+               }
+               if (((targ->targ_pkt->pkt_flags & FLAG_SILENT) == 0) ||
+                   sst_debug) {
+                       scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst",
+                           level, bp->b_blkno, 0, sst_cmds,
+                           targ->targ_devp->sd_sense);
+               }
+       } else if ((level >= sst_error_reporting) || sst_debug) {
+               scsi_errmsg(targ->targ_devp, targ->targ_pkt, "sst",
+                   level, bp->b_blkno, 0, sst_cmds, targ->targ_devp->sd_sense);
+       }
+
+       return (rval);
+}
+
+
+/*
+ * Command completion routine. Check the returned status of the
+ * command
+ */
+static int
+sst_check_error(struct scsi_target *targ, struct buf *bp)
+{
+       struct scsi_pkt *pkt = targ->targ_pkt;
+       int             action;
+       struct sst_private *sstprivp = (struct sst_private *)(pkt->pkt_private);
+
+       if (SCBP(pkt)->sts_busy) {
+               /*
+                * Target was busy. If we're not out of retries, call
+                * timeout to restart in a bit; otherwise give up and
+                * reset the target. If the fail on error flag is
+                * set, give up immediately.
+                */
+               int tval = (pkt->pkt_flags & FLAG_DIAGNOSE) ? 0
+                                                           : SST_BSY_TIMEOUT;
+
+               if (SCBP(pkt)->sts_is) {
+                       /*
+                        * Implicit assumption here is that a device
+                        * will only be reserved long enough to
+                        * permit a single i/o operation to complete.
+                        */
+                       tval = sst_io_time * drv_usectohz(1000000);
+               }
+
+               if ((int)targ->targ_retry_ct++ < sst_retry_count) {
+                       if (tval) {
+                               (void) timeout(sst_restart, (caddr_t)targ,
+                                   tval);
+                               action = JUST_RETURN;
+                               SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+                                   "Target busy, retrying\n");
+                       } else {
+                               action = COMMAND_DONE_ERROR;
+                               SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+                                   "Target busy, no retries\n");
+                       }
+               } else {
+                       /*
+                        * WARNING: See the warning in sst_handle_incomplete
+                        */
+                       SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                           "Resetting Target\n");
+                       if (!scsi_reset(ROUTE(targ), RESET_TARGET)) {
+#ifdef SCSI_BUS_RESET
+                               SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                                   "Resetting SCSI Bus\n");
+                               if (!scsi_reset(ROUTE(targ), RESET_ALL)) {
+                                       sst_log(targ->targ_devp, CE_WARN,
+                                           "SCSI bus reset failed\n");
+                               }
+#else SCSI_BUS_RESET
+                               sst_log(targ->targ_devp, CE_WARN,
+                                   "Reset Target failed\n");
+#endif SCSI_BUS_RESET
+                       }
+                       action = COMMAND_DONE_ERROR;
+               }
+       } else if (SCBP(pkt)->sts_chk) {
+               action = QUE_SENSE;     /* check condition - get sense */
+               if (targ->targ_arq) {
+                       SST_LOG(targ->targ_devp, SST_CE_DEBUG1,
+                           "Check Condition with Auto Sense enabled!\n");
+               } else {
+                       SST_LOG(targ->targ_devp, SST_CE_DEBUG2,
+                           "Check Condition\n");
+               }
+       } else {
+               targ->targ_retry_ct = 0;
+               SST_LOG(targ->targ_devp, SST_CE_DEBUG2, "Command Complete\n");
+               /*
+                * pkt_resid will reflect, at this point, a residual
+                * of how many bytes were not transferred; a non-zero
+                * pkt_resid is an error.
+                */
+               if (pkt->pkt_resid) {
+                       action = COMMAND_DONE;
+                       bp->b_resid += pkt->pkt_resid;
+               } else {
+                       sstprivp->priv_amtdone += sstprivp->priv_amt;
+                       if (sstprivp->priv_amtdone < bp->b_bcount)
+                               action = CONTINUE_PKT;
+                       else
+                               action = COMMAND_DONE;
+               }
+       }
+       return (action);
+}
+
+
+/*
+ * -----------------------------------------------------------------------------
+ *     Error Message Data and Routines
+ */
+
+/*
+ * Log a message to the console and/or syslog with cmn_err
+ */
+/*ARGSUSED*/
+static void
+sst_log(struct scsi_device *devp, int level, const char *fmt, ...)
+{
+       auto char name[16];
+       auto char buf[256];
+       va_list ap;
+
+       if (devp) {
+               (void) sprintf(name, "%s%d", ddi_get_name(devp->sd_dev),
+                   ddi_get_instance(devp->sd_dev));
+       } else {
+               (void) sprintf(name, "sst");
+       }
+
+       va_start(ap, fmt);
+       (void) vsprintf(buf, fmt, ap);
+       va_end(ap);
+
+       switch (level) {
+       case CE_CONT:
+       case CE_NOTE:
+       case CE_WARN:
+       case CE_PANIC:
+               cmn_err(level, "%s:\t%s", name, buf);
+               break;
+
+       case SST_CE_DEBUG4: if (sst_debug < 4) break;
+       /*FALLTHROUGH*/
+       case SST_CE_DEBUG3: if (sst_debug < 3) break;
+       /*FALLTHROUGH*/
+       case SST_CE_DEBUG2: if (sst_debug < 2) break;
+       /*FALLTHROUGH*/
+       case SST_CE_DEBUG1:
+       /*FALLTHROUGH*/
+       default:
+               cmn_err(CE_CONT, "^%s:\t%s", name, buf);
+               break;
+       }
+}
+
+/*
+ * Print a readable error message
+ * Note: This uses the arrays 'sst_cmds' and 'sst_errors' defined in
+ *      this file.
+ */
+
+#define        BUFSZ   256
+
+/*
+ * Print a buffer readably
+ */
+static void
+hex_print(char *msg, void *cptr, int len)
+{
+       int i = 0, j;
+       char    buf[BUFSZ];
+       char    *cp = cptr;
+
+       bzero(buf, BUFSZ);
+       for (i = 0; i < len; i++) {
+               /*
+                * make sure there's room for longest %x (i.e., 8 for
+                * a negative number) plus space (1) plus zero (1)
+                */
+               if ((j = strlen(buf)) >= (BUFSZ - 10)) {
+                       buf[BUFSZ-2] = '>';
+                       buf[BUFSZ-1] = 0;
+                       break;          /* cp too long, give up */
+               }
+               (void) sprintf(&buf[j], "%x ", cp[i]);
+       }
+       cmn_err(CE_CONT, "^%s: %s\n", msg, buf);
+}
+
+static void
+sst_dump_cdb(struct scsi_target *tgt, struct scsi_pkt *pkt, int cdblen)
+{
+       static char     hex[] = "0123456789abcdef";
+       char            buf [256];
+       u_char          *cdb;
+       char            *p;
+       int             i;
+
+       (void) sprintf(buf, "CDB = [");
+       p = &buf[strlen(buf)];
+       cdb = pkt->pkt_cdbp;
+       for (i = 0; i < cdblen; i++, cdb++) {
+               if (i > 0)
+                       *p++ = ' ';
+               *p++ = hex[(*cdb >> 4) & 0x0f];
+               *p++ = hex[*cdb & 0x0f];
+       }
+       *p++ = ']';
+       *p++ = '\n';
+       *p = 0;
+       sst_log(tgt->targ_devp, CE_CONT, buf);
+}
diff --git a/contrib/sst/sst.conf b/contrib/sst/sst.conf
new file mode 100644 (file)
index 0000000..989d9d9
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 1992,1997, by Sun Microsystems, Inc.
+# All rights reserved.
+#
+#      "@(#)sst.conf 1.5       97/09/14 SMI"
+#
+# Hardware Configuration file for sst, a Simple SCSI Target driver
+# If you have more than one device attached, add more lines for the
+# extra target/lun combinations (see sd.conf for an example)
+#
+
+name="sst" class="scsi" target=5 lun=0;
+
+# For attaching sst to a specific target:
+# name="sst"
+#        parent="/iommu@f,e0000000/sbus@f,e0001000/espdma@f,400000/esp@f,800000"
+#        target=4 lun=0;
+
+#
+# For targets which support a logical unit number other than zero,
+# change the lun field as appropriate, or for multiple logical
+# unit numbers per target, add entries as follows:
+#
+#      name="sst" class="scsi" target=5 lun=1;
+#
diff --git a/contrib/sst/sst_def.h b/contrib/sst/sst_def.h
new file mode 100644 (file)
index 0000000..d4bbc85
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 1997, by Sun Microsystems, Inc.
+ * All Rights Reserved
+ */
+
+/*
+ * This file is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify this file without charge, but are not authorized to
+ * license or distribute it to anyone else except as part of a product
+ * or program developed by the user.
+ *
+ * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * This file is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even
+ * if Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Defines and structures used only within the driver, sst.c
+ */
+
+#ifndef        _SST_DEF_H
+#define        _SST_DEF_H
+
+#pragma ident  "@(#)sst_def.h  1.13    97/10/02 SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if    defined(_KERNEL) || defined(_KMEMUSER)
+
+#include <sys/note.h>
+
+/*
+ * Driver compile options
+ */
+
+/*
+ * This driver does not reset the SCSI bus. Instead we just give up
+ * and complain if the target hangs. If the bus is really stuck, one
+ * of the Sun drivers (e.g. sd) will reset it. If you decide that
+ * your device is critical and you should in fact reset the bus in
+ * this driver, turn on this define below:
+#define        SCSI_BUS_RESET
+ */
+
+/*
+ * Local definitions, for clarity of code
+ */
+#define        SST_DEVINFO(t)  (((t)->targ_devp)->sd_dev)
+#define        SST_MUTEX(t)    (&((t)->targ_devp)->sd_mutex)
+#define        ROUTE(t)        (&((t)->targ_devp)->sd_address)
+
+#define        SCBP(pkt)       ((struct scsi_status *)(pkt)->pkt_scbp)
+#define        SCBP_C(pkt)     ((*(pkt)->pkt_scbp) & STATUS_MASK)
+#define        CDBP(pkt)       ((union scsi_cdb *)(pkt)->pkt_cdbp)
+
+#define        SST_CE_DEBUG1   ((1 << 8) | CE_CONT)
+#define        SST_CE_DEBUG2   ((2 << 8) | CE_CONT)
+#define        SST_CE_DEBUG3   ((3 << 8) | CE_CONT)
+#define        SST_CE_DEBUG4   ((4 << 8) | CE_CONT)
+#define        SST_LOG         if (sst_debug) sst_log
+#define        SST_DEBUG_ENTER if (sst_debug) debug_enter
+
+
+/*
+ * Private info for scsi targets.
+ *
+ * Pointed to by the un_private pointer
+ * of one of the SCSI_DEVICE structures.
+ */
+struct scsi_target {
+       struct scsi_pkt *targ_rqs;      /* ptr to request sense command pkt */
+       struct scsi_pkt *targ_pkt;      /* ptr to current command pkt */
+       struct  buf     *targ_sbufp;    /* for use in special io */
+       kcondvar_t      targ_sbuf_cv;   /* conditional variable for sbufp */
+       kcondvar_t      targ_pkt_cv;    /* conditional variable for pkt */
+       kcondvar_t      targ_suspend_cv; /* conditional variable for  */
+                                       /* suspended state */
+       int             targ_sbuf_busy; /* Wait Variable */
+       int             targ_pkt_busy;  /* Wait Variable */
+       int             targ_retry_ct;  /* retry count */
+       u_int           targ_state;     /* current state */
+       u_int           targ_arq;       /* ARQ mode on this tgt */
+       struct scsi_device *targ_devp; /* back pointer to SCSI_DEVICE */
+       struct buf      *targ_rqbp;     /* buf for Request Sense packet */
+       int             targ_suspended; /* suspend/resume */
+       int             targ_pm_suspended; /* power management suspend */
+       int             targ_power_level; /* PM power level */
+};
+
+_NOTE(MUTEX_PROTECTS_DATA(scsi_device::sd_mutex, scsi_target))
+
+struct sst_private {
+       struct buf      *priv_bp;       /* bp associated with this packet */
+       /*
+        * To handle partial DMA mappings, target may need several
+        * SCSI commands to satisfy packet.  Keep track of remaining
+        * data in this packet in the following two fields.
+        */
+       u_int           priv_amt;       /* bytes requested in this chunk */
+       u_int           priv_amtdone;   /* bytes done so far in current pkt */
+};
+
+_NOTE(DATA_READABLE_WITHOUT_LOCK(scsi_target::{targ_devp targ_rqs
+       targ_state targ_sbufp targ_arq}))
+
+_NOTE(SCHEME_PROTECTS_DATA("stable data",
+       scsi_device))
+
+_NOTE(SCHEME_PROTECTS_DATA("Unshared data",
+       scsi_target::targ_pkt scsi_arq_status scsi_status
+       buf scsi_pkt sst_private uio uscsi_cmd scsi_cdb))
+
+/*
+ * Driver states
+ */
+#define        SST_STATE_NIL           0
+#define        SST_STATE_CLOSED        1
+#define        SST_STATE_OPEN          2
+
+/*
+ * Parameters
+ */
+
+#define        SST_IO_TIME     30      /* default command timeout, 30sec */
+
+/*
+ * 5 seconds is what we'll wait if we get a Busy Status back
+ */
+#define        SST_BSY_TIMEOUT         (drv_usectohz(5 * 1000000))
+
+/*
+ * Number of times we'll retry a normal operation.
+ *
+ * This includes retries due to transport failure
+ * (need to distinguish between Target and Transport failure)
+ */
+#define        SST_RETRY_COUNT         30
+
+/*
+ * sst_callback action codes
+ */
+#define        COMMAND_DONE            0
+#define        COMMAND_DONE_ERROR      1
+#define        QUE_COMMAND             2
+#define        QUE_SENSE               3
+#define        JUST_RETURN             4
+#define        CONTINUE_PKT            5
+
+/*
+ * Special pkt flag just for this driver.
+ * NB: Other pkt_flags defines are in scsi_pkt.h.
+ */
+#define        FLAG_SENSING    0x0400  /* Running request sense for failed pkt */
+
+#endif /* defined(_KERNEL) || defined(_KMEMUSER) */
+
+/*
+ * Ioctl commands
+ */
+#define        SSTIOC          ('S' << 8)
+#define        SSTIOC_READY    (SSTIOC|0)      /* Send a Test Unit Ready command */
+#define        SSTIOC_ERRLEV   (SSTIOC|1)      /* Set Error Reporting level */
+
+
+
+#if defined(_SYSCALL32)
+
+/*
+ * This is an example of how to support a 32-bit application issuing
+ * an ILP32 ioctl into a 64-bit driver.  Using fixed data-size
+ * types, define a 32-bit version of the data structure as used
+ * by the ioctl, along with functions or macros to convert between
+ * the ILP32 and LP64 models.  The LP64 driver can then use
+ * ddi_copyin/ddi_copyout to access the application's copy of
+ * the data structure, but internally use the usual ILP32 or
+ * LP64 model, as compiled.
+ */
+struct sst_uscsi_cmd32 {
+       int             uscsi_flags;    /* read, write, etc. see below */
+       short           uscsi_status;   /* resulting status  */
+       short           uscsi_timeout;  /* Command Timeout */
+       caddr32_t       uscsi_cdb;      /* cdb to send to target */
+       caddr32_t       uscsi_bufaddr;  /* i/o source/destination */
+       size32_t        uscsi_buflen;   /* size of i/o to take place */
+       size32_t        uscsi_resid;    /* resid from i/o operation */
+       u_char          uscsi_cdblen;   /* # of valid cdb bytes */
+       u_char          uscsi_rqlen;    /* size of uscsi_rqbuf */
+       u_char          uscsi_rqstatus; /* status of request sense cmd */
+       u_char          uscsi_rqresid;  /* resid of request sense cmd */
+       caddr32_t       uscsi_rqbuf;    /* request sense buffer */
+       caddr32_t       uscsi_reserved_5;       /* Reserved for Future Use */
+};
+
+
+/*
+ * Convert application's ILP32 uscsi_cmd to LP64
+ */
+#define        sst_uscsi_cmd32touscsi_cmd(u32, ucmd)                           \
+       ucmd->uscsi_flags       = u32->uscsi_flags;                     \
+       ucmd->uscsi_status      = u32->uscsi_status;                    \
+       ucmd->uscsi_timeout     = u32->uscsi_timeout;                   \
+       ucmd->uscsi_cdb         = (caddr_t)u32->uscsi_cdb;              \
+       ucmd->uscsi_bufaddr     = (caddr_t)u32->uscsi_bufaddr;          \
+       ucmd->uscsi_buflen      = (size_t)u32->uscsi_buflen;            \
+       ucmd->uscsi_resid       = (size_t)u32->uscsi_resid;             \
+       ucmd->uscsi_cdblen      = u32->uscsi_cdblen;                    \
+       ucmd->uscsi_rqlen       = u32->uscsi_rqlen;                     \
+       ucmd->uscsi_rqstatus    = u32->uscsi_rqstatus;                  \
+       ucmd->uscsi_rqresid     = u32->uscsi_rqresid;                   \
+       ucmd->uscsi_rqbuf       = (caddr_t)u32->uscsi_rqbuf;            \
+       ucmd->uscsi_reserved_5  = (void *)u32->uscsi_reserved_5;
+
+
+/*
+ * Convert drivers's LP64 uscsi_cmd back to IPL32
+ */
+#define        sst_uscsi_cmdtouscsi_cmd32(ucmd, u32)                           \
+       u32->uscsi_flags        = ucmd->uscsi_flags;                    \
+       u32->uscsi_status       = ucmd->uscsi_status;                   \
+       u32->uscsi_timeout      = ucmd->uscsi_timeout;                  \
+       u32->uscsi_cdb          = (caddr32_t)ucmd->uscsi_cdb;           \
+       u32->uscsi_bufaddr      = (caddr32_t)ucmd->uscsi_bufaddr;       \
+       u32->uscsi_buflen       = (size32_t)ucmd->uscsi_buflen;         \
+       u32->uscsi_resid        = (size32_t)ucmd->uscsi_resid;          \
+       u32->uscsi_cdblen       = ucmd->uscsi_cdblen;                   \
+       u32->uscsi_rqlen        = ucmd->uscsi_rqlen;                    \
+       u32->uscsi_rqstatus     = ucmd->uscsi_rqstatus;                 \
+       u32->uscsi_rqresid      = ucmd->uscsi_rqresid;                  \
+       u32->uscsi_rqbuf        = (caddr32_t)ucmd->uscsi_rqbuf;         \
+       u32->uscsi_reserved_5   = (caddr32_t)ucmd->uscsi_reserved_5;
+
+#endif /* _SYSCALL32 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SST_DEF_H */
diff --git a/contrib/sst/sstest.c b/contrib/sst/sstest.c
new file mode 100644 (file)
index 0000000..4cc1365
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 1992,1997 Sun Microsystems, Inc.  All Rights Reserved.
+ * Sun considers its source code as an unpublished, proprietary
+ * trade secret, and it is available only under strict license
+ * provisions.  This copyright notice is placed here only to protect
+ * Sun in the event the source is deemed a published work.
+ * Disassembly, decompilation, or other means of reducing the
+ * object code to human readable form is prohibited by the license
+ * agreement under which this code is provided to the user or
+ * company in possession of this copy.
+ *
+ * RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
+ * Government is subject to restrictions as set forth in
+ * subparagraph (c)(1)(ii) of the Rights in Technical Data and
+ * Computer Software clause at DFARS 52.227-7013 and in similar
+ * clauses in the FAR and NASA FAR Supplement.
+ *
+ * These examples are provided with no warranties of any kind,
+ * including without limitation accuracy and usefulness, and Sun
+ * expressly disclaims all implied warranties of merchantability,
+ * fitness for a particular purpose and non-infringement. In no
+ * event shall Sun be liable for any damages, including without
+ * limitation, direct, special, indirect, or consequential damages
+ * arising out of, or relating to, use of these examples by customer
+ * or any third party. Sun is under no obligation to provide support
+ * to customer for this software.
+ *
+ * sstest.c
+ * A simple tst program for the sample SCSI target driver.
+ * To compile: cc (or acc) sstest.c -o sstest
+ * Note: the full ANSI conformance flag, -Xt, fails because of the
+ *      system header files.
+ *
+ * Usage:
+ *     sstest [device] [command] [arg]
+ * Device is the /devices entry
+ * Command can be:
+ *     open - just open and close the device
+ *     read [arg] - read a block. If arg is specifed, printf the result
+ *     write [arg] - write a block. With arg, write "arg"
+ *     rew - send the SCSI Rewind command (tests the USCSICMD ioctl)
+ *     tur - send the SCSI Test Unit Ready command (SSTIOC_READY ioctl)
+ *     errlev [lev] - set the error reporting level to <lev> (see sst_def.h)
+ */
+
+#pragma        ident   "@(#)sstest.c 1.4       97/04/07 SMI"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/scsi/impl/uscsi.h>
+#include <sys/scsi/generic/commands.h>
+#include "sst_def.h"
+
+#define        BUFSZ   512
+
+static void usage(char *name);
+
+main(int argc, char *argv[])
+{
+       int     fd, nbytes, level, arg;
+       char    buf[BUFSZ], *progname, *devname, *command, *value;
+       struct uscsi_cmd                scmd;
+
+       if ((argc != 3) && (argc != 4)) {
+               usage(argv[0]);
+               /*NOTREACHED*/
+       }
+
+       progname = argv[0];     /* name of this program */
+       devname = argv[1];      /* full path of device name */
+       command = argv[2];      /* command to do */
+       value = argv[3];        /* command's argument if present */
+       arg = (argc == 4);      /* command has arg */
+
+
+
+       (void) sprintf(buf, "%s", devname);
+       if ((fd = open(buf, O_RDWR)) == -1) {
+               perror(buf);
+               exit(1);
+               /*NOTREACHED*/
+       }
+
+       (void) memset((void *)buf, 0, BUFSZ);
+
+       if (strcmp(command, "open") == 0) {
+               fprintf(stdout, "Device opened\n");
+       } else if (strcmp(command, "read") == 0) {
+               if ((nbytes = read(fd, buf, BUFSZ)) != BUFSZ) {
+                       perror("read");
+                       (void) close(fd);
+                       exit(1);
+                       /*NOTREACHED*/
+               }
+               if (argc == 4) {
+                       fprintf(stdout, "Read \"%s\"\n", buf);
+               } else {
+                       fprintf(stdout, "Read %d bytes\n", nbytes);
+               }
+
+       } else if (strcmp(command, "write") == 0) {
+               if (arg) {
+                       strcpy(buf, value);
+               }
+               if ((nbytes = write(fd, buf, BUFSZ)) != BUFSZ) {
+                       perror("write");
+                       (void) close(fd);
+                       exit(1);
+                       /*NOTREACHED*/
+               }
+               fprintf(stdout, "Wrote %d bytes\n", nbytes);
+
+       } else if (strcmp(command, "rew") == 0) {
+               (void) memset((void *) &scmd, 0, sizeof (scmd));
+               scmd.uscsi_flags = 0;
+               scmd.uscsi_timeout = 30;
+               buf[0] = SCMD_REWIND;
+               scmd.uscsi_cdb = buf;
+               scmd.uscsi_bufaddr = NULL;
+               scmd.uscsi_buflen = 0;
+               scmd.uscsi_cdblen = CDB_GROUP0;
+
+               if (ioctl(fd, USCSICMD, &scmd) == -1) {
+                       perror("rewind ioctl");
+                       (void) close(fd);
+                       exit(1);
+                       /*NOTREACHED*/
+               }
+               fprintf(stdout, "Device rewound, status = 0x%x\n",
+                   scmd.uscsi_status);
+       } else if (strcmp(command, "errlev") == 0) {
+               if (argc != 4) {
+                       usage(progname);
+                       /*NOTREACHED*/
+               } else if ((level = atoi(value)) == 0) {
+                       fprintf(stderr, "Bad error level %s\n", value);
+                       exit(1);
+               }
+
+               if (ioctl(fd, SSTIOC_ERRLEV, &level) == -1) {
+                       perror("Set error level ioctl");
+                       (void) close(fd);
+                       exit(1);
+                       /*NOTREACHED*/
+               }
+       } else if (strcmp(command, "tur") == 0) {
+               if (ioctl(fd, SSTIOC_READY, NULL) == -1) {
+                       perror("Ready ioctl");
+                       (void) close(fd);
+                       exit(1);
+                       /*NOTREACHED*/
+               }
+               fprintf(stdout, "Device is ready\n");
+       } else {
+               fprintf(stderr, "Unknown command: %s\n", command);
+               usage(progname);
+               /*NOTREACHED*/
+       }
+
+       (void) close(fd);
+       exit(0);
+}
+
+static void
+usage(char *name)
+{
+       (void) fprintf(stderr, "Usage: %s: [device] [command]\n", name);
+       (void) fprintf(stderr, "Device is the full path name of device\n");
+       (void) fprintf(stderr, "Command is one of:\n");
+       (void) fprintf(stderr, "\topen - just open & close\n");
+       (void) fprintf(stderr, "\tread - read a block\n");
+       (void) fprintf(stderr, "\twrite - write a block\n");
+       (void) fprintf(stderr, "\trew - send the SCSI 'rewind' command\n");
+       (void) fprintf(stderr, "\terrlev [lev] - Set the error "
+           "reporting level\n");
+       (void) fprintf(stderr, "\ttur - send the SCSI 'test unit ready'"
+           "command\n");
+       exit(1);
+       /*NOTREACHED*/
+}
diff --git a/docs/DUMPER-API b/docs/DUMPER-API
new file mode 100644 (file)
index 0000000..2438a51
--- /dev/null
@@ -0,0 +1,392 @@
+AMANDA DUMPER API
+
+Last modified $Date: 1998/10/06 17:17:00 $
+
+by Alexandre Oliva <oliva@dcc.unicamp.br>
+
+1. INTRODUCTION
+
+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 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 connected to a tape unit.
+
+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 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 run.
+
+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 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 functionality.
+
+2. THE PROBLEM
+
+Different backup programs present distinct requirements; some must be
+run as super-user, whereas others can be run under other user-ids.
+Some require a directory name, the root of the tree to be backed up;
+others prefer a raw device name; some don't even refer to local disks
+(SAMBA).  Some wrappers may need to know a filesystem type in order to
+decide which particular backup program to use (dump, vdump, vxdump,
+xfsdump, backup).
+
+Some provide special options for estimates, whereas others must be
+started as if a complete dump were to be performed, and must be killed
+as soon as they print an estimate.
+
+Furthermore, the output formats of these backup programs vary wildly.
+Some will print estimates and total sizes in bytes, in 512-byte tape
+blocks units, in Kbytes, Mbytes, Gbytes, and possibly Tbytes in the
+near future.  Some will print a timestamp for the backup; some won't.
+
+There are also restrictions related with possible scheduling policies.
+For example, some backup programs only support full backups or
+incrementals based on the last full backup (0-1).  Some support full
+backups or incrementals based 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 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 manipulate them.
+
+The DUMPER API must accomodate for all these variations.
+
+3. OVERVIEW OF THE API
+
+We are going to define a standard format of argument lists that the
+backup driver will provide to wrapper programs, and the expected
+result of the execution of these wrappers.
+
+The first argument to a wrapper should always be a command name.  If
+no arguments are given, or an unsupported command is requested, an
+error message should be printed to stderr, and the program should
+terminate with exit status 1.
+
+3.1.  The `support' command
+
+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 supported before issuing the
+corresponding commands.
+
+3.1.1. 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 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 maximum incremental
+level it supports, i.e., 9.  A sample session would be:
+
+% /usr/local/amanda/libexec/wrappers/DUMP support level-incrementals hda0
+9
+
+Note that the result of this support command may depend on filesystem
+information, so the disklist filesystem entry should be specified as a
+command line argument.  In the next examples, we are not going to use
+full pathnames to wrapper scripts any more.
+
+We could have defined a `support' command for full backups, but I
+can't think of a backup program that does not support full backups...
+
+3.1.2. The `index' subcommand
+
+The ability to produce index files is also subject to an invocation of
+`support' command.  When the support sub-command is `index', like in
+the invocation below, the wrapper must print a list of valid indexing
+mechanisms, one per line, most preferred first.  If indexing is not
+supported, nothing should be printed, and the exit status should be 1.
+
+       DUMP support index hda0
+
+The currently known indexing mechanisms are:
+
+output: implies that the command `index-from-output' generates an
+index file from the output produced by the backup program (for
+example, from `tar -cv').
+
+image: implies that the command `index-from-image' generates an index
+file from a backup image (for example, `tar -t').
+
+direct: implies that the `backup' command can produce an index file as
+it generates the backup image.
+
+parse: implies that the `backup-parse' command can produce an index
+file as it generates the backup formatted output .
+
+The indexing mechanisms will be explicitly requested with the additionnal
+option `index-<mode>' in the `backup' and `backup-parse' command invocation.
+
+`index-from-image' should be supported, if possible, even if other
+index commands are not, since it can be used in the future to create
+index files from previously backed up filesystems.  
+
+3.1.3. The `parse-estimate' subcommand
+
+The `parse-estimate' support subcommand print a list of valid mechanisms to
+parse the estimate output and write the estimate size to its output, the
+two mechanisms are:
+
+direct: implies that the `estimate' command can produce the estimate output.
+
+parse: implies that the `estimate-parse' command can produce the estimate
+output when fed with the `estimate' output.
+
+The estimate parsing mechanisms will be explicitly requested with the 
+additionnal option `estimate-<mode>' in the `estimate' and 
+`estimate-parse' command invocation.
+
+3.1.4. The `parse-backup' subcommand
+
+The `parse-backup' support subcommand print a list of valid mechanisms to
+parse the backup stderr, the two mechanisms are:
+
+direct: implies that the `backup' command can produce the
+backup-formatted-ouput.
+
+parse: implies that the `backup-parse' command can produce the 
+backup-formatted-ouput when fed with the `backup' stderr.
+
+The backup parsing mechanisms will be explicitly requested with the 
+additionnal option `backup-<mode>' in the `backup' and `backup-parse'
+command invocation.
+
+3.1.5. Others subcommands
+
+Some other standard `support' sub-commands are `exclude' and
+`exclude-list'.
+
+3.1.6.
+
+One may think (and several people did :-) that there should be only
+one support command, that would print information about all supported
+commands.  The main arguments against this proposal have to do with
+extensibility:
+
+1) the availability of commands might vary from filesystem to
+filesystem.  No, I don't have an example, I just want to keep it as
+open as possible :-)
+
+2) one support subcommand may require command line arguments that
+others don't, and we can't know in advance what these command line
+arguments are going to be
+
+3) the output format and exit status conventions of a support command
+may vary from command to command; the only pre-defined convention is
+that, if a wrapper does not know about a support subcommand, it should
+return exit status 1, implying that the inquired feature is not
+supported.
+
+3.2. 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)
+
+A selfcheck request would go like this:
+
+       DUMP selfcheck hda0 option option=value ...
+
+The options specified as command-line arguments are dumptype options
+enabled for that disk, such as `index', `norecord', etc.  Unknown
+options should be ignored.  For each successful check, a message such
+as:
+
+OK [/dev/hda0 is readable]
+OK [/usr/sbin/dump is executable]
+
+Errors should be printed as:
+
+ERROR [/etc/dumpdates is not writable]
+
+If selfcheck needs super-user (or some other user, for that matter)
+access to perform some tests, it should print to the standard output
+either:
+
+USER root
+GROUP operator
+
+The backup driver should then arrange to re-run the script as the
+specified user/group.  Security concerns may impose restrictions on
+privileges that can be given to wrapper scripts.  For example, we may
+require that, in order to run a wrapper script as any other user or
+group, the wrapper script must be in a separate directory, say
+/usr/local/amanda/libexec/wrappers-protected, and that the script, its
+containing directory and all its parents must only be writable by
+root.
+
+The need for starting programs as other users requires amandad (that
+will incorporate all the functionality from selfcheck, sendsize and
+sendbackup) to be setuid-root.  However, it will fork a child process
+and drop to the amanda user privileges as soon as possible.  This
+child process will be driven through a pipe, and it will be able to
+start services as other users, in a way that no other user, not even
+the backup operator, will be able to run arbitrary commands.
+
+
+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 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 one dump program is available; this information can help
+automatically selecting the appropriate dump program.
+
+
+The exit status of selfcheck and of this alternate script are probably
+going to be disregarded.  Anyway, for consistency, selfcheck should
+return exit status 0 for complete success, 1 if any failures have
+occurred and 2 if it needs additional permissions (USER/GROUP).  Note
+that, if the wrapper needs a special permission to perform a test, it
+should not report a failure for that test.
+
+3.3. The `estimate' and `estimate-parse' commands
+
+Estimate requests can be on several different forms.  An estimate of a
+full backup may be requested, or estimates for level- or
+timestamp-based incrementals:
+
+  DUMP estimate full hda0 option ...
+  DUMP estimate level 1 hda0 option ...
+  DUMP estimate diff 1998:09:24:01:02:03 hda0 option ...
+
+
+If the backup program needs privileged access to obtain estimates, it
+should just print:
+
+USER root
+GROUP operator
+
+and exit, with exit status 2.  If requested estimate type is not
+supported, exit status 3 should be returned.
+
+If the option `estimate-direct' is set, then the `estimate' command
+should write to stdout the estimated size, in bytes, a pair of numbers
+that, multiplied by one another, yield the estimated size in bytes.
+
+If the option `estimate-parse' is set, then the `estimate' command 
+should write 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 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 1, except for the already listed cases of exit status 2
+and 3.
+
+3.4. The `backup' and `backup-parse' commands
+
+The syntax of `backup' is the same as that of `estimate'.  The backup
+image should be written to standard output, whereas stderr should be
+used for the user-oriented output of the backup program and other
+messages.
+
+If the option `backup-direct' is set, then the `backup' command should 
+write to stderr a formatted-output-backup.
+
+If the option `backup-parse' is set, then the `backup' command 
+should write to stderr the informations needed by the `backup-parse'
+command, that should edit its input so that it prints to standard
+output a formatted-output-backup.
+
+If the option `no-record' is set, then the `backup' command should
+not modify its state file (ex. dump should not modify /etc/dumpdates).
+
+The syntax of `backup-parse' is identical to that of `backup'.
+
+The syntax of the formatted-output-backup is as follow:
+All lines should start with either `| ' for normal output, `? ' for
+strange output or `& ' for error output.  If the wrapper can determine
+the total backup size from the output of the backup program, it should
+print a line starting with `# ', followed by the total backup size in
+bytes or by a pair of numbers that, multiplied, yield the total backup
+size; this number will be used for consistency check.
+
+The option `index-direct' should cause commands `backup' to output 
+the index directly to file descriptor 3.  The option `index-parse' 
+should cause commands `backup-parse' to output the index directly to
+file descriptor 3.  The syntax of the index file is described in the 
+next section.
+
+3.5. The `index-from-output' and `index-from-image' commands
+
+The syntax of the `index-from-output' and `index-from-image' commands
+is identical to the one of `backup'.  They are fed the backup output
+or image, and they must produce a list of files and directories, one
+per line, to the standard output.  Directories must be identified by
+the `/' termination.
+
+After the file name and a blank space, any additional information
+about the file or directory, such as permission data, size, etc, can
+be added.  For this reason, blanks and backslashes within filenames
+should be quoted with backslashes.  Linefeeds should be represented as
+`\n', although it is not always possible to distinguish linefeeds in
+the middle of filenames from ones that separate one file from another,
+in the output of, say `restore -t'.  It is not clear whether we should
+also support quoting mechanisms such as `\xHH', `\OOO' or `\uXXXX'.
+
+3.6. The `restore' command
+
+Yet to be specified.
+
+3.7. The `print-command' command
+
+This command must be followed by a valid backup or restore command,
+and it should print a shell-command that would produce an equivalent
+result, i.e., that would perform the backup to standard output, or
+that would restore the whole filesystem reading from standard input.
+This command is to be included in the header of backup images, to ease
+crash-recovery.
+
+4. Conclusion
+
+Well, that's all.  Drop us a note at the amanda-hackers mailing list
+if you have suggestions to improve this document and/or the API.  Some
+help on its implementation would be welcome too.
diff --git a/docs/EXCLUDE b/docs/EXCLUDE
new file mode 100644 (file)
index 0000000..0e6d81d
--- /dev/null
@@ -0,0 +1,317 @@
+============
+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:
+
+       * 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 older versions.  This was compiled from my personal
+experience and with help from the members of the amanda-users
+mailing list when I was originally setting this up, to whom I wish
+to 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 gnutar 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.
+
+The GNU version of tar, (gnutar or gtar), reads its data at a
+file system, (or higher), level and does include the option to
+exclude specific files and/or directories.  It should be mentioned
+here that tar will change the access times on files.   Tar has the
+ability to preserve the access times however, doing so effectively
+disables incremental backups since resetting the access time alters
+the inode change time, which in turn causes the file to look like
+it needs to be archived again.
+
+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-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 usually different
+machines but are not required to be, and may be the same machine.
+Parts of this setup are on the server and some are on the client.
+
+***************
+** IMPORTANT **
+***************
+
+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 want to exclude "/var/log/somefile", then your
+exclude file would contain "./log/somefile".  You may use one
+exclude file in multiple dump types 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 there are no errors in the current setup.
+
+       $ amcheck -cl CLIENT
+
+Output should look something like below for success:
+
+       Amanda Tape Server Host Check
+       -----------------------------
+
+       /path/to/holding-disk: 4771300 KB disk space available, that's plenty.  
+       Amanda Backup Client Hosts Check
+       -------------------------------- 
+       Client check: 1 host checked in 0.084 seconds, 0 problems found.
+
+Next make sure that gnutar is the dump program currently in use.
+The easiest way to tell if your dumptype is using gnutar is to run
+the following:
+
+       $ amadmin exclude-test disklist CLIENT
+
+Among all the output is the "program" value currently in use. This
+value is also specified with the "program" option in the dumptype.
+If the dumptype has the line "program GNUTAR" your setup should ready
+to exclude data.
+
+If gnutar is not in use add the line "program GNUTAR" to the
+dumptype, and then run amcheck again to verify that backups should
+work. The capitalization of GNUTAR is required in the current
+version of amanda.
+
+The dumptype should look something like: 
+
+define dumptype exclude-test {
+        comment "test dumptype for documentation"
+        priority high
+        program "GNUTAR"
+}
+
+=============================
+Choosing an exclude mechanism
+=============================
+
+If the need is to exclude only one file or directory then the
+easiest way to accomplish this is to exclude an individual item
+explicitly in the dumptype.  If the need is to exclude multiple
+files or directories then use an Exclude List.
+
+==================
+Exclude Mechanisms
+==================
+
+** Exclude an individual item explicitly in the dumptype **
+
+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 dumptype at a time.  Any path
+specified to be excluded must be encapsulated with quotes.  Continuing
+with our example from above "/var/log/somefile" and using the same
+dumptype as above, the dumptype would now look like:
+
+define dumptype exclude-test {
+        comment "test dumptype for documentation"
+        priority high
+        program "GNUTAR"
+        exclude "./log/somefile"
+}
+
+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 the Troubleshooting section below.  This
+completes the setup of excluding an individual item in the dumptype.
+
+
+** Utilize an Exclude List **
+
+An exclude list is a file that resides on the CLIENT machine and
+contains paths to be excluded, one per line.   This file can be in
+any location on the CLIENT so long as the same path is specified
+in the dumptype.  Some find /usr/local/etc/amanda an appropriate
+location, but it is up to you.  I personally like to have a
+subdirectory for exclude files but it is up to you where you place
+this file.  
+
+The exclude file may also be placed in the area being archived.
+This is an easy way to have a different exclusion file for each
+disklist entry without needing separate dumptype definitions.  To
+use this technique, enter a path relative to the area being archived
+as the exclude file below instead of an absolute path.
+
+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 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.
+Remember that all paths are relative. The exclude list would look
+like:
+
+               ./log/XFree86.0.log
+               ./log/maillog
+
+Make sure that permissions are restricted on this file.  Run the
+following as root, where exclude-filename is the name of the file
+you just created.  For 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 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:
+
+       exclude list "/usr/local/etc/amanda/exclude/exclude-filename"
+
+The new dumptype should look something like: 
+
+       define dumptype exclude-test{
+               comment "test dumptype for documentation"
+               priority high
+               program "GNUTAR"
+               exclude list "/usr/local/etc/amanda/exclude/exclude-filename"
+       }
+
+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 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 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 directories "a",
+"b", and "c" need to be archived, while "d" and "e" should not.
+This can be accomplished by not specifying "d" and "e" in the
+disklist.  Using the same dumptype and host in the above examples
+the disklist would contain:
+
+       CLIENT /examples/a      exclude-test
+       CLIENT /examples/b      exclude-test
+       CLIENT /examples/c      exclude-test
+
+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.
+
+=========
+Expresion
+=========
+
+Quiz: what is the difference between the following entries in
+an exclude list?
+
+1 ./foo
+2 ./foo/
+3 ./foo/*
+
+case 1 directory ./foo won't be in the backup image (that's what you want)
+case 2 matches nothing (don't use it)
+case 3 directory ./foo will be in the backup image but nothing below it.
+
+==================
+Wildcard Expansion
+==================
+
+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:
+
+Exclude any  file or directory that ends in ".log" e.g. ppp.log,
+XFree86.0.log
+
+       ./*.log 
+
+Exclude any file or directory with the string "log"  e.g. logfile,
+maillog, syslog, ppp.log, XFree86.0.log
+
+       */*log*
+
+Exclude any file or directory that starts with string "cron" and ends in
+".gz" e.g. cron.1.gz, cron.2.gz, log/cron.1.gz
+
+       ./*cron*.gz
+
+The question mark can be used to specify a single character.  e.g.
+log.1, log.2, etc
+
+       ./log.?
+
+===============
+Troubleshooting 
+===============
+
+1. If you find that you are having trouble getting the exclude
+patterns to match correctly, check out this really cool script
+written by John R. Jackson.
+
+       ftp://gandalf.cc.purdue.edu/pub/amanda/gtartest-exclude  
+
+This script allows you to test your patterns before placing them
+in an exclude list or in the dumptype.  Instructions on how to run
+the script are included in the script.
+
+2. Broken gnutar?  There are versions of gnutar that do not correctly
+exclude data.  Version 1.12 (plus the Amanda patches from
+www.amanda.org) are known to work correctly, as does version 1.13.19
+(and later).  Anything else is questionable.
+
+3. The ps command is your friend.  Connect to CLIENT and run a "ps
+ax | grep tar", (ps -ef | grep tar) on Solaris, to see exactly how
+the tar command is running.  Look in the output for the --exclude
+or --exclude-from options in the running tar process.  For example:
+
+       $ ps ax | grep tar 
+   11078 ?        R      0:37 /bin/tar --create --directory /var
+   --listed-incremental /var/lib/amanda/gnutar-lists/CLIENTvar_0.new
+   --sparse --one-file-system --ignore-failed-read --totals --file
+   /dev/null --exclude-from=/usr/local/etc/amanda/exclude-test/exclude.var
+   .
+
+In the above output notice the string "--exclude-from=".  The string
+following the "=" is the exclude file currently in use.  If the
+string was "--exclude" then the string following the "=" is the
+file or directory that is currently set to be excluded.
+
+4. Check out the book "Unix Backup & Recovery", written by W. Cutris
+Preston.  It contains a chapter on Amanda written by John R. Jackson.
+It can be read online at www.amanda.org.
+
+5. Contact the amanda-users mailing list.  Subscription information
+is available at www.amanda.org.
+
+
+Written by Andrew Hall <ahall@secureworks.net> August 6, 2001. 
diff --git a/docs/FAQ b/docs/FAQ
new file mode 100644 (file)
index 0000000..148a872
--- /dev/null
+++ b/docs/FAQ
@@ -0,0 +1,525 @@
+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 its documentation.
+
+New entries and modifications are welcome; send them to
+amanda-users@amanda.org or amanda-hackers@amanda.org.
+
+You may also want to take a look at the Amanda FAQ-O-Matic
+http://www.amanda.org/fom-serve/cache/1.html
+
+
+Q: Why does Amanda fail to build on my system?
+
+A: 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 across platforms, or at least run
+`make distclean' before running `configure' on another platform.
+
+   Another common reason for failure, that causes link-time errors, is
+a problem 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
+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 libraries, so binaries will be larger, but you may
+worry about that later.
+
+   You may also want to take a look at docs/SYSTEM.NOTES, as well as
+to the Amanda Patches Page (check www.amanda.org) 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, showing the last few lines of the failed build.
+
+
+Q: Why does `amdump' report that all disks failed?
+
+A: 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.
+
+
+Q: Why does `amcheck' say `port NNN is not secure'?
+
+A: 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 `chmod u+s' them again, if `chown'
+drops the setuid bit.
+
+
+Q: Why does `amcheck' claim that the tape is `not an amanda tape'?
+
+A: 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/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.
+
+   If you have labeled any tapes using the rewiding device
+configuration, you'll have to label them again.
+
+
+Q: Why does `amcheck' report `selfcheck request timed out'?
+
+A: 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.
+
+   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, amandad is not starting properly, or it
+lacks permission to create /tmp/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), 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 the
+INSTALL file for details.  Check the inetd man-page for possible
+differences between the standard inetd.conf format and the one in your
+system.
+
+   Pay special attention to typos in inetd.conf; error messages will
+probably appear in /var/adm/messages or /var/log/messages if you have
+typed the amandad program name incorrectly.  Make sure the same user
+that you have specified at configure-time (--with-user=<USERNAME>) is
+listed in 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 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 inetd.conf so as to run
+amandad, you should no longer get the `selfcheck request timed out'
+message.  A nice tool to help make sure inetd is really listening on
+the amandad port is lsof, available at
+ftp://vic.cc.purdue.edu/pub/tools/unix/lsof.
+
+
+Q: Why does `amandad.debug' contain `error receiving message'?
+
+A: One possibility is that you have run `amandad' from the command
+line prompt and typed anything instead of waiting for it to time-out:
+in this case, it will 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
+`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 a UDP service; check /etc/services and /etc/inetd.conf.
+
+
+Q: Why does `amcheck' say `access as <username> not allowed...'
+
+A: There must be something wrong with .amandahosts configuration (or
+.rhosts, if you have configured --without-amandahosts).
+
+   First, if the <username> is not what you expect (i.e., not what you
+have specified in the --with-user flag, at configure time), check the
+inetd configuration file: you must have specified the wrong username
+there.
+
+   Make sure you specify the names exactly as they appear in the error
+message after the `@' sign in .amandahosts/.rhosts.  You'll need a
+fully-qualified domain name or not, depending on how your client
+resolves IP addresses to host names.
+
+
+Q: Why does `amcheck' report `ip address #.#.#.# is not in the ip list 
+list for <hostname>'?
+
+A: 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.
+
+
+Q: Why does `amcheck' say `cannot overwrite active tape'?
+
+A: 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, 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.
+
+
+Q: Why does `amcheck' tell me `DUMP program not available'?
+
+A: Because the `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 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 it as release 1.12 or newer; release 1.11.8 may work,
+but estimates will be slow as hell.
+
+
+Q: Which tape changer configuration should I use in amanda.conf?
+
+A: If you only have one tape unit, you have two choices: (i) don't use
+a tape changer at all, i.e., set runtapes to 1, set tapedev to the
+non-rewinding device corresponding to the tape unit, and comment out
+tpchanger, changerfile and changerdev; or (ii) set up chg-manual, so
+that you can change tapes manually.  If you select chg-manual, you
+will not be able to start `amdump' as a cron job, and you should
+always run `amflush -f', because chg-manual will ask you to press
+return in the terminal where you started the controlling program.
+
+   If you have several tape units, which you want to use to emulate a
+tape changer, you want chg-multi.  Even if you do own a real tape
+changer, that operates based on ejecting a tape or such, chg-multi may
+be useful.
+
+   Actual tape changers usually require specialized changer programs,
+such as `mtx', `chio' or specific system calls.  The availability of
+these programs is much more dependent on the operating system you're
+running than on the particular tape changer hardware you have.
+
+   `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 the script, which shouldn't be
+hard to do.
+
+   In section BUILT-IN TAPE CHANGERS of docs/TAPE.CHANGERS, 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 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 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! :-)
+
+
+Q: Should I use software or hardware compression?
+
+A: When you enable software compression, you drastically reduce the
+compression that might be achieved by hardware.  In fact, tape drives
+will usually use *more* tape if you tell them to try to further
+compress already compressed 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 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 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.
+
+
+Q: How can I configure Amanda so that it performs full backups on the
+week-end and incrementals on weekdays?
+
+A: 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 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.
+
+
+Q: 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?
+
+A: 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 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 with tapes only, say once a week, to perform full
+backups, and run it without tape on the other days, so that it
+performs incremental backups and stores them in the holding disk.
+Once or twice a week, you flush all backups in the holding disk to a
+single tape.
+
+   If you don't trust your holding disk, and you'd rather have all
+your data on tapes daily, you can create an alternate configuration,
+with two tapes, that 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.
+
+
+Q: How can I configure Amanda for long-term archiving?
+
+A: 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.
+
+
+Q: Can I backup separate disks of the same host in different
+configurations?
+
+A: 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 is ignored.  The effect
+is two-fold: (i) if another configuration requests for estimates, the
+request will be ignored, and the requester will end up timing out;
+(ii) if another configuration has already finished the estimates, and
+is now requesting for backups, the backup requests will time-out.
+
+  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 services names to contact the
+clients, i.e., different port numbers.  This 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 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 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 entries, according to history
+data).  You'll also have to delay the starttime (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.
+
+
+Q: Can Amanda span large filesystems across multiple tapes?
+
+A: 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, where
+more up-to-date information is likely to be found about this project.
+
+   The current work-around is to use GNU tar to back up subdirectories
+of the huge filesystem separately.  But be aware of the problems
+listed in the question about `results missing'.
+
+
+Q: What's the difference between option `skip-full' and `strategy nofull'?
+
+A: `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 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 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:
+it might perform a level 2 on the next day, just after you have run
+the level 0, so, if the disk should crash, you'd have to restore a
+level 0 then a level 2, but not the level 1!  Not a real problem, but
+definitely strange, eh?
+
+
+Q: Why does `amdump' report `results missing'?
+
+A: 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 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.  The
+probability of getting this problem has been considerably reduced
+since we increased the maximum UDP packet size from 1Kb to 64Kb, but
+some operating systems may not support such large packets.
+
+   One possible work-around is to try to shorten the pathnames of the
+directories and the exclude file names, so that more requests fit in
+the UDP packet.  You may create short-named links in some directory
+closer to the root (/) so as to reduce the length of names.  I.e.,
+instead of backing up /usr/home/foo and /usr/home/bar, create the
+following links:
+       /.foo -> /usr/home/foo
+       /.bar -> /usr/home/bar
+then list /.foo and /.bar in the disklist.
+
+   Another approach is to group sub-directories in backup sets,
+instead of backing up them all separately.  For example, create
+/usr/home/.bkp1 and move `foo' and `bar' into it, then create links so
+that the original pathnames remain functional.  Then, list
+/usr/home/.bkp1 in the disklist.  You may create as many `.bkp<N>'
+directories as you need.
+
+   A simpler approach, that may work for you, is to backup only a
+subset of the subdirectories of a filesystem separately.  The others
+can be backed up together with the root of the filesystem, using an
+exclude list that prevents duplicate backups.
+
+
+Q: Why does `amdump' report `disk offline'?
+
+A: Well, assuming the disk is not really off line :-), it may be a
+permission problem, but then, `amcheck' would have reported it.
+
+   Another possible reason for this failure is a filesystem error,
+that causes 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 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.
+
+
+Q: What if `amdump' reports `dumps way too big, must skip incremental
+dumps'?
+
+A: 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 `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 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.
+
+
+Q: `amdump' reported `infofile update failed'.  What should I do?
+
+A: 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.
+
+
+Q: Why does Amanda sometimes promote full dumps?
+
+A: To spread the full dumps along the dumpcycle, so that daily runs
+take roughtly 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 with `amadmin <conf> balance'.  If
+you find the results surprising, you may want to adjust dumpcycle or
+runspercycle.
+
+
+Q: Why does `amrecover' report `no index records' or `disk not found'?
+
+A: The most common cause of this problem is not having enabled index
+generation in amanda.conf.  The `index yes' option must be present in
+every dumptype for whose disks indexes should be generated.
+
+   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 (--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'.
+
+
+Q: 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?
+
+A: 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 may be files with extensions such as .dir
+and .pag.
+
+   Then, remove any log files from the log directory:
+log.<TIMESTAMP>.<count> and amdump.<count>.  Finally, remove the
+tapelist file, stored in the directory that contains amanda.conf,
+unless amanda.conf specifies otherwise.  Depending on the tape changer
+you have selected, you may also want to reset its state file.
+
+
+Q: The man-page of DUMP says that active filesystems may be backed up
+inconsistently.  What does Amanda do to prevent inconsistent backups?
+
+A: Nothing.  When you back up an active filesystem, there are two
+possibilities:
+
+1) dump may print strange error messages about invalid blocks, then
+fail; in this case, Amanda will retry the backup on the next run
+
+2) 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 unlocks the database when appropriate.
diff --git a/docs/HOWTO-AFS b/docs/HOWTO-AFS
new file mode 100644 (file)
index 0000000..6255810
--- /dev/null
@@ -0,0 +1,8 @@
+You need to download the following package if you want to backup AFS volume
+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.
diff --git a/docs/HOWTO-CYGWIN.html b/docs/HOWTO-CYGWIN.html
new file mode 100644 (file)
index 0000000..033c879
--- /dev/null
@@ -0,0 +1,240 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+  <meta name="GENERATOR" content="SGML-Tools 1.0.9">
+  <title>Amanda on Cygwin HOWTO</title>
+  <link href="amanda-cyg-howto-4.html" rel="next">
+  <link href="amanda-cyg-howto-2.html" rel="previous">
+  <link href="amanda-cyg-howto.html#toc3" rel="contents">
+  <meta name="author" content="Doug Kingston">
+</head>
+<body>
+<h1 style="text-align: center;"><a name="s3">Amanda on Cygwin HOWTO</a></h1>
+<p>by Doug Kingston, 30 January 2003.&nbsp; 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.<br>
+</p>
+<p>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.&nbsp; Please send annotations and corrections
+to amanda-hackers@amanda.org. I can be reached as dpk (at)
+randomnotes.org (do the obvious).<br>
+</p>
+<h2><a name="Install">1. Install Cygwin</a></h2>
+<h2> </h2>
+<p> The following Cygwin packages are required for binary installation
+(may be incomplete): </p>
+<ul>
+  <li> Category BASE: standard</li>
+  <li>Category MISC: gzip<br>
+  </li>
+  <li>Category MISC: tar<br>
+  </li>
+  <li> Category NET: inetutils</li>
+</ul>
+<p> You need also these packages to build from source (may be
+incomplete): </p>
+<ul>
+  <li> Category DEVELOP: ALL</li>
+  <li> Category INTERPRETERS: m4, gawk ?</li>
+  <li> Category LIBS:<span style="font-style: italic;">default
+selection? (libc, libiconv, others?)<br>
+    </span></li>
+</ul>
+I have most or the basic utilities and libraries installed so I cannot
+give you a more specific list of what is required.&nbsp; If someone has
+a more definitive list, I would appreciate and email to amanda-hackers.<br>
+<br>
+One user reported some problems with access rights when running under
+Cygwin, which he solved by setting the CYGWIN environment variable to
+nontsec.&nbsp; I do not believe this is necessary if you run the amanda
+daemon as System (see below).<br>
+<p> </p>
+<h2><a name="Compile"></a>2. Other Preparation</h2>
+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.&nbsp; For Windows 95/98/ME this is probably a non-issue.&nbsp;
+The most privileged account on the Windows 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.&nbsp; On Unix we would run as root, with
+equivalent access permissions.&nbsp; I have also chose to run under the
+'Administrators' group, another standard Windows group.&nbsp; Ensure
+these exist before you continue - or identify another account to
+use.&nbsp; The Cygwin installation postinstall script should have
+already populated /etc/passwd and /etc/group with these entries.<br>
+<ul>
+  <li>Make sure that System (or SYSTEM) has a home directory specified
+in /etc/passwd.</li>
+</ul>
+I used <span style="font-family: monospace;">/home/root</span>.&nbsp;
+You'll need to put the .amandahosts file here later.&nbsp; The relevant
+lines from my /etc/passwd file are:<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">SYSTEM:*:18:18:,S-1-5-18:/home/root:</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">root:*:18:18:,S-1-5-18:/home/root:</span></div>
+<h2><a name="Compile">3. Compile Amanda</a></h2>
+After installing Cygwin, unpack the Amanda sources, typically in
+/usr/src/amanda or something similar.&nbsp; In the Amanda directory, you
+will need to execute:<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">automake&nbsp;
+# this may not be necessary in the official release</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">autoconf&nbsp; # this may not be
+necessary in the official release</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">./configure --without-server \</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp; --without-force-uid \</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp; --with-user=<span
+ style="font-style: italic;">yourlogin</span> \</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp; --with-group=Administrators</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">make</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">make&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+# yes, I needed to run it a second time</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">make install</span><br>
+</div>
+<br>
+The use of&nbsp; your own login instead of SYSTEM requires some
+explanation.&nbsp; If you were to call runconfigure with SYSTEM instead
+of your own login id as part of the -with-user parameter, the
+installation process will fail due to the way Cygwin and the NT/W2K/XP
+security system interact.&nbsp; Once you chown a file to another user
+(like SYSTEM) you are no longer able to chgrp or chmod the file.&nbsp;
+The installations process will abort at this point.&nbsp; By installing
+the files owned by yourself, you will be able to chgrp and chmod them
+as expected.&nbsp; Note that you still RUN as SYSTEM from inetd.conf
+(see below).<br>
+<h2><a name="Configure">4. Configure Cygwin files</a> </h2>
+<p>You have to modify some config files: </p>
+<ul>
+  <li>/etc/inetd.conf: cleanup un-needed entries:</li>
+</ul>
+<p style="margin-left: 40px;">Comment out any entries you do not need
+by placing a '#' at the start of the lines.&nbsp; This is just good
+practice, and if any of the entries reference non-existent users (e.g.
+uucp) inetd may not start up.</p>
+<ul>
+  <li> /etc/inetd.conf: add
+    <blockquote><code> amanda  dgram   udp     wait    System
+/usr/local/libexec/amandad amandad </code></blockquote>
+ATTENTION: Use tabs, don't use spaces.<br>
+  </li>
+</ul>
+<ul>
+  <li> create <span style="font-family: monospace;">/home/root/.amandahosts</span>
+(or whereever System's home directory is):
+    <pre> &lt;amanda server&gt; &lt;amanda user&gt; <br></pre>
+  </li>
+</ul>
+Then create the following AMANDA directories and the amandates file:
+<blockquote><code> mkdir -p /usr/local/var/amanda/gnutar-lists<br>
+  <br>
+mkdir /tmp/amanda<br>
+  <br>
+touch /etc/amandates<br>
+  </code></blockquote>
+<h2><a name="Configure">5. Configure Windows system files</a> </h2>
+Update the Windows services list<br>
+<ul>
+  <li> &lt;WINDIR&gt;\Services: add
+    <blockquote><code> amanda              10080/udp                   #
+amanda backup services<br>
+amandaidx           10082/tcp                   # amanda backup services<br>
+amidxtape           10083/tcp                   # amanda backup services<br>
+      </code></blockquote>
+  </li>
+</ul>
+where WINDIR is C:\WINNT\system32\drivers\etc or something
+similar.&nbsp; The last two lines are needed if you want to use
+amrecover.<br>
+<br>
+Ensure that the default Windows PATH environment variable include your
+Cygwin /bin directory.&nbsp; This is necessary since inetd and hence the
+amandad that it spawns will not have the advantage of being started by
+the standard bash shell startup script and won't find the needed dynamic
+libraries (e.g. cygwin1.dll). My PATH is:<br>
+<span style="font-family: monospace;"><br>
+&nbsp;
+%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\cygwin\bin</span><br>
+<br>
+This is on XP; My Computer, right click - Properties, click on
+Environment Variables (at the bottom).&nbsp; Yours may vary, but make
+sure the Cygwin bin directory is represented somewhere in the PATH.<br>
+<p> </p>
+<h2><a name="Inetd">6. Configure Inetd to run automatically as a service</a> </h2>
+<p>If you want to test your installation, you can call inetd from bash
+prompt: </p>
+<blockquote><code> /usr/sbin/inetd -d </code></blockquote>
+<p> </p>
+<h3>Windows 98/ME<br>
+</h3>
+<p> </p>
+<ul>
+  <li> To start after the user logs in: Create a shortcut to
+    <pre>c:\cygwin\usr\sbin\inetd.exe<br></pre>
+in
+    <pre>&lt;WINDIR&gt;\start menu\programs\startup<br></pre>
+  </li>
+  <li> To start before the user logs in: Add the string key
+    <pre>CygwinInetd=C:\cygwin\usr\sbin\inetd.exe<br></pre>
+under
+    <pre>HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices<br></pre>
+in the registry. You'll see a dos-like window on the startup: I not
+found a solution to iconize or to make invisible (suggestions are
+welcome).</li>
+</ul>
+<h3>Windows NT/2000/XP</h3>
+<p>From bash prompt, type: </p>
+<pre> /usr/sbin/inetd --install-as-service<br></pre>
+Then, to start/stop inetd service use the Services control panel or the
+following Windows command:
+<pre> net start/stop inetd<br></pre>
+<h2><a name="Notes"></a>7. Notes on Amanda backup options</h2>
+<p><span style="font-weight: bold; text-decoration: underline;">Compression</span><br>
+Currently, client side compression does not work, probably due to
+problems in pipe emulation in Cygwin.&nbsp; I have not tried to debug
+this yet.&nbsp; This may be addressed in a subsequent release, or it
+could be fixed in later releases of Cygwin.&nbsp; 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:</p>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">define
+dumptype srv-comp-tar {</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; global</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; comment
+"partitions dumped via tar with server compression"</span><br
+ style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; program
+"GNUTAR"</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; compress
+server fast</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; exclude list
+".amanda.exclude"</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">}</span></div>
+<p><span style="font-weight: bold; text-decoration: underline;">Exclude
+Lists</span><br>
+A note on exclude lists is also in order.&nbsp; If you specify a
+relative path, it will be expect ed that the file is in or relative to
+the root of the directory you are planning to dump.&nbsp; Typically this
+will not be '/' but '/cygdrive/c' or something similar if you want to
+get the Windows files and the Cygwin files.&nbsp; '/' is taken to be the
+root of the Cygwin tree, normally something like C:\cygwin or possibly
+C:\Program Files\cygwin.</p>
+<p><span style="font-weight: bold; text-decoration: underline;">Debugging
+Files</span><br>
+Amanda will leave debugging files in /tmp/amanda if it exists.&nbsp; I
+have recommended creating the directory above.&nbsp; <br>
+</p>
+<p><br>
+</p>
+</body>
+</html>
diff --git a/docs/HOWTO-FILE-DRIVER b/docs/HOWTO-FILE-DRIVER
new file mode 100644 (file)
index 0000000..8c8f655
--- /dev/null
@@ -0,0 +1,356 @@
+---
+
+       AMANDA FILE-DRIVER-USAGE HOWTO.
+
+---
+
+       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, configuration names and other parameters 
+       to your system.
+
+       Stefan G. Weichinger, November - December, 2003
+
+---
+
+       Since release 2.4.3 AMANDA supports the usage of a output
+       driver called "file".  See the AMANDA-man page, 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.
+
+---
+
+POSSIBLE USES
+       
+---
+
+       - test installations.
+       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 to a bunch of harddisks. You can
+       create CD/DVD-sized backups which you can burn onto optical 
+       disks later.
+       
+       - raid installations.
+       You can use the file-driver to backup onto a set of
+       file tapes hosted on 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.
+       
+---
+
+SETUP
+
+---
+
+BASICS
+
+       This guide assumes you have setup the basic AMANDA-services
+       as described in the "INSTALL"-file.
+
+       The configuration in this HOWTO is called "daily".
+       The file tapes are also called "vtapes" in this document, which 
+       stands for "virtual tapes".
+
+       Please be sure to understand the differences between holding disks and
+       file tapes. The two serve different purposes; holding disks allow for
+       parallelism of multiple DLE's being backed up while file tapes are a 
+       replacement for physical tapes.
+
+       Before beginning you will need to decide on (a) dedicated part(s)
+       of your hard 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.  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 performance due to massive head-moving
+       in your harddisk, resulting from copying data between the
+       filesystems.
+
+---
+
+STEPS
+
+Step 0.  Prepare the filesystem(s) used for the tapes.
+
+       Decide on where to put your files, create the
+       appropriate partition(s) and filesystem(s) and mount them.
+
+       In our example we have the dedicated partition "hdc1", 
+       mounted on /amandatapes for vtape storage.
+
+       $ mount
+       ...
+       /dev/hdc1 on /amandatapes type reiserfs (rw)
+       ...
+
+       Make sure there is space left.
+       Determine the amount of space you will use.
+
+       $ df -h /amandatapes
+       Filesystem      Size  Used  Avail  Use%   Mounted on
+       /dev/hdc1        20G    0G    20G    0%   /amandatapes
+
+       In our example we have 20GB diskspace left on /amandatapes.
+
+Step 1.  Determine length and number of tapes
+
+       After deciding on the number of vtapes you want to create,
+       evenly allocate the available space among them.
+
+       Look at the following rule of thumb:
+
+       As many types file systems exhibit dramatically reduced performance
+       when they are nearly full I have chosen to allocate
+       only 90% of the available space. So we have:
+
+       (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 may also wish to use more space than that.
+
+       So you could determine possible combinations of tapelength/tapecycle
+       with the more general formula:
+
+       Available Space >= tapelength * tapecycle
+
+
+       In our example we take the conservative approach:
+
+       20 GB * 0.9 = 18 GB to use and so we could create the
+       following combinations:
+
+       18 GB = 18 GB * 1
+       18 GB =  9 GB * 2
+       18 GB =  6 GB * 3
+       18 GB =  3 GB * 6
+       18 GB = .........   you get the picture. 
+
+       Using only one tape is generally considered a bad idea
+       when it comes to backup, so we should use at least 3
+       tapes (for testing purposes), better 6 or more tapes.
+
+       18 GB =  3 GB * 6   so we get the value 3GB for the
+       tapelength if we want to use 6 tapes.
+
+Step 2.  Create a tapetype definition.
+
+       Add a new tapetype definition similar to the following to your amanda.conf.
+       I named my definition "HARD-DISK".  Choose whatever name you
+       consider appropriate.
+
+       define tapetype HARD-DISK {
+               comment "Dump onto hard disk"
+               length 3072 mbytes      # specified in mbytes to get the exact size of 3GB
+       }
+
+       You don´t have to specify the "speed"-parameter (as it is
+       commonly listed in tapetype definitions and reported by 
+       the program "amtapetype"). AMANDA does not use this parameter.
+
+       There is also an optional "filemark"-parameter, which indicates
+       the amount of space wasted after each tape-section. Leave it
+       blank and AMANDA uses the default of 1KB.
+
+Step 3. 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 TAPE.CHANGERS.
+
+       Right now there are two scripts that can be used with vtapes.
+       These scripts take different approaches to the handling of tapes.
+
+       The script chg-multi handles many drives with a tape in each drive.
+       The script chg-disk handles a library with one drive and multiple tapes.
+
+       So with vtapes you could look at it this way:
+
+       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.
+
+       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.
+
+       To use chg-disk you need to have at least amanda-2.4.4p1-20031202.
+
+       Choose the one that fits your way of vtape-handling and -maintenance.
+
+       In this HOWTO I only cover the use of chg-disk.
+       Usage of chg-multi is pretty similar and will maybe covered in a later
+       version of this document.
+
+Step 4. Set up your tape-config.
+
+       In the general section you have to set the parameters tapecycle,
+        tapetype, tpchanger, changerfile, tapedev, rawtapedev and changerdev.
+
+        Example:
+
+        $ vi /usr/local/etc/amanda/daily/amanda.conf
+        ...
+
+        tapecycle 6
+        tapetype HARD-DISK
+        tpchanger "chg-disk"
+        changerfile "/usr/local/etc/amanda/daily/changer"
+       tapedev  "file:/amandatapes/daily"
+
+        This reflects the use of your defined tapetype.
+
+        The "tapecycle"-parameter tells AMANDA how much tapes can be used.
+        Set this value according to the number of tapes you want to use.
+
+        The "tapetype"-parameter points to the tapetype definition you have
+        created in Step 2.
+
+        The "tpchanger"-parameter tells AMANDA to use the generic
+        tape-changer-script to handle the virtual tapes. You
+        can think of it as a virtual tape-changer-device.
+
+        The "changerfile"-parameter is used to give chg-disk the "prefix"
+       for the "%s-changer, %s-clean, %s-slot" files it needs.
+       Use something like "changer" in your config-dir.
+       Please note that this file does NOT have to exist, but it won't
+       hurt anyway.
+
+       The "tapedev"-parameter tells the chg-disk-script where the 
+       root-dir for your vtapes is. 
+       In our example the vtape-files go to
+       /amandatapes, and to separate multiple configurations we decided
+       to use subdirectories according to the configuration name "daily".
+
+Step 5. Create the virtual tapes.
+
+       Now you have to create the tape-directories. 
+       chg-disk needs a directory structure like:
+
+       slot_root_dir -|
+                      |- info
+                      |- data -> slot1/
+                      |- slot1/
+                      |- slot2/
+                      |- ...
+                      |- slotn/
+
+       where 'slot_root_dir' is the tapedev 'file:xxx' parameter 
+       and 'n' is the tapecycle parameter.
+
+       So in our example we do:
+
+       $ mkdir /amandatapes/daily
+
+       for the 'slot_root_dir' and
+
+       $ mkdir /amandatapes/daily/slot1
+       $ mkdir /amandatapes/daily/slot2
+       ....
+
+       for the virtual slots that will later contain the vtapes.
+
+        If you have many vtapes to create and their names follow a pattern
+        you may be able to do them all with a single loop such as:
+
+        $ for n in 1 2 3 4 5 6 7 8 9 10 11 12
+        > do
+        >    mkdir /amandatapes/daily/slot${n}
+        > done
+
+       Create the info-file:
+
+       $ touch /amandatapes/daily/info
+       
+       and link the first slot to the data-file (to "load" the vtape
+       in the first slot):
+
+       $ ln -s /amandatapes/daily/slot1 /amandatapes/daily/data
+
+       Make sure the AMANDA-user has write-permissions on these directories:
+
+       $ chown -R <amanda_user> /amandatapes
+       $ chgrp -R <amanda_group> /amandatapes
+       $ chmod -R 750 /amandatapes
+
+Step 8. Label the virtual tapes.
+
+       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>]
+
+       Example:
+
+       $ amlabel daily daily1 slot 1
+       ....
+       $ amlabel daily daily2 slot 2
+       ....
+
+       If you have many vtapes to label and their names follow a pattern
+       you may be able to do them all with a single loop such as:
+
+       $ for n in 01 02 03 04 05 06 07 08 09 10 11 12
+       > do
+       >    amlabel daily daily${n} slot ${n}
+       > done
+
+       Label all your created tapes according to the
+       "labelstr"-parameter in your amanda.conf.  Consult the
+       amlabel-man-page for details.
+
+Step 9. Test your setup with amcheck.
+
+       Run amcheck daily (or, more general, amcheck <config>)
+       and look for anything AMANDA complains about.
+
+       A proper output looks like:
+
+       $ amcheck daily
+       Amanda Tape Server Host Check
+       -----------------------------
+       Holding disk /amhold: 6924940 KB disk space available,
+       that's plenty
+       amcheck-server: slot 2: date 20031115 label daily02
+       (exact label match)
+       NOTE: skipping tape-writable test
+       Tape daily02 label ok
+       Server check took 0.377 seconds
+
+       Recheck your files if errors occur.
+
+----
+
+
+THAT'S IT!  YOU ARE READY TO RUN, UNLESS WE FORGOT
+SOMETHING.  PLEASE send mail to amanda-users@amanda.org if
+you have any comments or questions.  We're not afraid of
+negative reviews, so let us have it!
diff --git a/docs/INDEXING b/docs/INDEXING
new file mode 100644 (file)
index 0000000..417bbff
--- /dev/null
@@ -0,0 +1,383 @@
+This file describes how the index files are generated and how amrecover
+is used.
+
+
+Database Format
+---------------
+
+The database consists of a directory tree of the format:
+  $host/$disk/$date_$level.gz
+
+The host and disk are those listed in the disklist file, the "$host/$disk/"
+is like the curinfo database, '/' are changed for '_'.
+There is an index file for each dump, the name of the file is made
+of the date and the level, they will have the .gz suffix if they are
+compressed with gzip.
+
+ex. The file foo/_usr/19991231_0.gz is the index of the level 0 made on
+    19991231 of the disk /usr of the host foo.
+
+The files are ASCII text files containing a list of the directory
+and files of the dump, one per line.  Each entry is the filename
+relative to the mount point, starting with a /, e.g., /home/user1/data
+from the disk mounted on /home would generate the entry /user1/data.
+The index files are stored in compressed format (eg gzip or compress).
+
+
+Database Browsing
+-----------------
+
+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 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 user can then roam around a virtual file system using "ls" and "cd"
+much like in a FTP client.  The file system contains all files backed
+up on the specified date, or before that date, back to the last level 0
+backup.  Only the most recent version of any file is shown.
+
+As the file system is traversed, the user can add and delete files to a
+"shopping list", and print the list out.
+
+
+File Extraction
+---------------
+
+When a user has built up a list of files to extract, they can be
+extracted by issuing the command "extract" within amrecover.
+
+Files are extracted by the following, for each different tape needed.
+
+As part of the installation, a "tape server" daemon amidxtaped is
+installed on one or more designated hosts, which have an attached tape
+drive.  This is used to read the tapes.  See the config files for the
+options for specifying a default.
+
+Amrecover contacts amidxtaped on the tape server host specifying which
+tape device to use, which host and disk files are needed for.  On the
+tape server host, amidxtaped exec's amrestore to get the dump image
+file off the tape, and returns the data to amrecover.
+
+If dumps are stored compressed for the client, then amrecover pipes the
+data through the appropriate uncompression routine to uncompress it
+before piping it into restore, which then extracts the required files
+from the dump image.
+
+Note that a user can only extract files from a host running the same
+operating system as he/she is executing amrecover on, since the native
+dump/restore tools are used - unless gnutar is used.
+
+
+Protocol Between amindexd and amrecover
+---------------------------------------
+
+The protocol talked between amindexd and amrecover is a simple ASCII
+chat protocol based on that used in FTP.  Amrecover sends a 1 line
+command, and amindexd replies with a 1 line or multi-line reply.  Each
+line of the reply starts with a three digit code, starting with a '5'
+if an error occurred.  For 1 line replies, and the last line of a
+multi-line reply, the 4th character is a space.  For all but the last
+line of a multi-line reply, the 4th character is a '-'.
+
+The commands and replies other than acknowledgments are:
+
+QUIT - finish up and close connection
+
+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
+
+DATE <date> - set date to date
+
+DHST - return dump history of current disk
+
+OISD <dir> - Opaque is directory? query.  Is the directory <dir>
+            present in the backups of the current disk back to and
+            including the last level 0 dump.
+
+OLSD <dir> - Opaque list directory.  Give all filenames present in
+            <dir> in the backups of the current disk back to and
+            including the last level 0 dump.
+
+ORLD <dir> - Opaque recursive list directory.  Give all filenames 
+            present in <dir> and subdir in the backups of the current
+            disk back to and including the last level 0 dump.
+
+TAPE - return value of tapedev from amanda.conf if set.
+
+DCMP - returns "YES" if dumps for disk are compressed, "NO" if dumps
+            aren't.
+
+
+
+INSTALLATION NOTES
+------------------
+
+
+1) Whether or not an index is created for a disk is controlled by a
+disk configuration option "index".  So, in amanda.conf you need to
+define a disktype with this option, e.g.,
+
+define dumptype comp-user-index {
+    comment "Non-root partitions on reasonably fast machines"
+    compress client fast
+    index yes
+    priority medium
+}
+
+2) You need to define disks that you want to generate an index for to
+be of one of the disktypes you defined which contain the index option.
+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
+"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.
+
+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 client software.  Its location may not be appropriate for your
+system and you may need to move it to a more accessible place such as
+/usr/local/bin.  See its man page for how to use it.
+
+
+Note that amindexd, amgetidx, amidxtaped, and amtrmidx all write debug
+files on the server in /tmp (unless this feature is disabled in the
+source code), which are useful for diagnosing problems.  Amrecover
+writes a debug file in /tmp on the machine it is invoked.
+
+
+PERMISSIONS
+-----------
+
+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.
+
+
+CHANGES FROM AMINDEX-1.0
+------------------------
+
+Get index directory from amanda.conf
+
+Integration into amanda-2.3.0.4.
+
+Rewriting of amgetidx to use amandad instead of using rsh/rcp.
+
+
+
+CHANGES FROM AMINDEX-0.3
+------------------------
+
+Support for index generation using gnutar
+
+Support for restoring files from within amrecover.
+
+Bug fixes:
+
+       * index/client/amrecover.c (guess_disk): 
+       Removed inclusion of mntent.h and use of MAXMNTSTR since this
+       was non-portable, as pointed out by Izzy Ergas
+       <erga00@nbhd.org>.
+
+       * index/client/display_commands.c (list_directory): 
+       Removed point where list_directory() could sleep for ever
+       waiting for input that wasn't going to come.
+
+       * index/server/amindexd.c
+         index/client/uscan.l
+       Installed patches from Les Gondor <les@trigraph.on.ca> to make
+       amrecover handle spaces in file names.
+
+       * server-src/amcontrol.sh: 
+       As pointed out by Neal Becker <neal@ctd.comsat.com> there were
+       still a few sh-style comments that needed conversion to
+       c-style.
+
+
+
+
+CHANGES FROM AMINDEX-0.2
+------------------------
+
+       * index/client/Makefile.in
+       * index/client/help.c
+       * index/client/amrecover.h
+       * index/client/uparse.y
+       * index/client/uscan.l
+       Added a help command.
+
+       * index/client/set_commands.c:
+       set_disk() and set_host() now check for empty extract list.
+       
+       * index/client/extract_list.c:
+       * index/client/amrecover.h:
+       * index/client/uparse.y:
+       * index/client/uscan.l:
+       Added clear extract list command.
+       
+       * index/client/set_commands.c (set_disk): 
+       Added code so working directory set to mount point.
+
+       * index/client/extract_list.c:
+       If the last item on a tape list is deleted, the tape list
+       itself is now deleted from the extract list.
+
+       * index/client/amrecover.c: 
+       * index/server/amindex.c:
+       If the server started up and found that the index dir doesn't
+       exist, then it exited immediately and the client got
+       informative message.  Corrected this so it is obvious what is
+       wrong to the user, since this is most likely to occur when
+       somebody is setting up for the first time and needs all the
+       help they can get.
+
+       * server-src/amgetidx.c
+       Added patch from Pete Geenhuizen
+       (pete@gasbuggy.rockledge.fl.us) so that it works even when
+       remote shell is csh.
+
+       * server-src/amcontrol.sh
+       * server-src/Makefile.in
+       Amcontrol is now parameterized like other scripts and run
+       through munge to generate installable version.
+
+       * index/server/amindexd.c (main): 
+       Added code to set userid if FORCE_USERID set.
+
+       * index/server/amindexd.c
+       Removed #define for full path of grep.  Assumed now to be on
+       path.
+
+       * client-src/createindex-dump.c
+       * client-src/sendbackup-dump.c
+       * man/Makefile.in
+       Added patch from Philippe Charnier (charnier@lirmm.fr) so they
+       work when things are installed with version numbers.  This was
+       also reported by Neal Becker (neal@ctd.comsat.com).  Also patch
+       to set installed man page modes and create directory if
+       needed.
+
+       * config/options.h-sunos4
+       Corrected definition for flex library.
+
+       * server-src/amtrmidx.c
+       Added some pclose() commands, used remove() instead of
+       system("rm ..").  Problems reported by Pete Geenhuizen
+       (pete@gasbuggy.rockledge.fl.us) on a system with small ulimits
+       set.
+
+       * index/server/amindexd.[ch]
+       * index/server/list_dir.c
+       * index/client/amrecover.c
+       * index/client/set_commands.c
+       * index/client/uparse.y
+       Changes developed with the help of Pete Geenhuizen
+       (pete@gasbuggy.rockledge.fl.us) to support disks specified by
+       logical names.  Also, now debug files generated by amrecover
+       include PID so multiple users can use amrecover simultaneously
+       and without file deletion permission problems.
+
+       * config/config.h-hpux: 
+       * config/config-common.h:
+       * server-src/amgetidx.c:
+       Changes from Neal Becker re remote shell, making it a
+       configuration parameter.
+
+       * config/options.h-sunos4
+       Had -Lfl instead of -lfl
+       
+
+
+CHANGES FROM AMINDEX-0.1
+------------------------
+
+       * index/client/uscan.l: 
+       added support for abbreviated date specs
+
+       * index/client/amrecover.c (guess_disk): 
+       guess_disk got disk_path wrong if mount point other than / (as
+       subsequently pointed out by Eir Doutreleau <ed@cti.ecp.fr>)
+       
+       * server-src/amtrmidx:
+       Added amtrmidx which removes old index files.
+
+       * index/client:
+       Added a pwd command
+
+       * server-src/amgetidx.c (main): 
+       Added use of CLIENT_LOGIN username on r commands.  (as pointed
+       out by Eric Payan <Eric.Payan@ufrima.imag.fr>)
+
+       * server-src/amgetidx.c:
+       Bug: It was copying from all clients irrespective of whether
+       the client was configured for indices.  A '}' in the wrong
+       place.
+
+       * server-src/amgetidx.c: 
+       Removed user configuration section.  Instead include amindexd.h
+       to get information.
+
+
+
+CHANGES/ADDITIONS TO 2.3.0
+--------------------------
+
+common-src/conffile.[ch]
+
+- added "index" as a valid option
+
+
+server-src/driverio.c
+
+- added code to optionstr() to write "index" into option string
+
+
+client-src/sendback-dump.c
+
+- added code to generate index if requested.
+
+client-src/indexfilename.[ch]
+client-src/createindex-dump.c
+
+- code to generate index.
+
+client-src/Makefile.in
+
+- a new target.  Another file for sendbackup-dump
+
+config/config-common.h
+
+- added def of restore.
+
+
+
+
+KNOWN BUGS
+----------
+
+- Empty directories don't get into the listing for a dump (at all dump
+levels).
+
+- When amrecover starts up, it tries to guess the disk and mount point
+from the current directory of the working system.  This doesn't work
+for disks specified by logical names, nor when an automounter is being
+used, or a link is in the path.
+
+
+Alan M. McIvor
+11 March 1997
diff --git a/docs/INSTALL b/docs/INSTALL
new file mode 100644 (file)
index 0000000..f2ce817
--- /dev/null
@@ -0,0 +1,380 @@
+Amanda INSTALLATION NOTES
+
+This document covers the compilation, installation, and runtime setup
+of Amanda 2.4.2 and higher.
+
+0. BEFORE DOING ANYTHING
+
+    A.  Read this document all the way through.
+
+    B.  Consult the docs/SYSTEM.NOTES file for installation notes
+       specific to particular operating systems.  There is often
+       important information there, so don't forget this step.
+
+    C.  Read docs/UPGRADE 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 docs/KERBEROS
+       for details on installing and running the kerberized version of
+       Amanda.
+
+    E.  Check the Amanda Patches Page, www.amanda.org/patches.html.
+
+1. COMPILING THE AMANDA SOURCES
+
+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).
+
+1.1. 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, we can install version 1.12 or 1.13.25.
+       gnutar 1.12 can be found at:
+
+               ftp://ftp.gnu.org/pub/gnu/tar/tar-1.12.tar.gz
+       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.
+
+       gnutar 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 docs/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.
+
+           $prefix/sbin                Amanda server side programs
+                                       --sbindir=
+           $prefix/libexec             Amanda backup client programs
+                                       --libexecdir=
+           $prefix/lib                 Amanda dynamic libraries
+                                       --libdir=
+           $prefix/etc/amanda          Runtime configuration files
+                                       --with-configdir=
+           $prefix/var/amanda/gnutar-lists
+                                       Directory for GNUtar lists (client)
+                                       --with-gnutar-listdir=
+           $prefix/man                 Directory for manual pages
+                                       --mandir=
+
+       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' 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.
+
+1.2. BUILDING AND INSTALLING THE BINARIES
+
+    A.  Back at the top-level source directory, build the sources:
+               1. make
+               2. su root; make install
+       If you want to change the compiler flags, you can do so like
+       this:
+               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:
+               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.
+
+2. SETTING UP YOUR AMANDA CONFIGURATION
+
+2.1. SETTING UP THE TAPE SERVER HOST
+
+    B.  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
+       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 "no-record"
+       option 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.
+
+    C.  Put amanda into your crontab.  Here's a sample:
+               0 16 * * 1-5 /usr/local/bin/amcheck -m confname
+               45 0 * * 2-6 /usr/local/bin/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.
+
+    D.  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.
+
+    E.  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):
+
+       #/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
+       }
+
+    F.  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
+       .amandahosts file so that the server host lets itself in.
+       This is a frequently encountered problem for new sites.
+
+
+2.2. 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.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.
+
+    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 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 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 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.
+
+THAT'S IT!  YOU ARE READY TO RUN, UNLESS WE FORGOT SOMETHING.  PLEASE
+send mail to 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 FAQ (in
+docs/FAQ) and at the Amanda home page, at http://www.amanda.org.
+Browsable archives of amanda mailing-lists are available there.
+
+By James da Silva <jds@cs.umd.edu> and others.
diff --git a/docs/INTERNALS b/docs/INTERNALS
new file mode 100644 (file)
index 0000000..91fb27f
--- /dev/null
@@ -0,0 +1,271 @@
+This is an attempt to document Amanda's internals.  Please feel free to make
+comments and suggest changes.  Text for new sections gratefully accepted!
+
+George.
+(George.Scott@cc.monash.edu.au)
+
+===============
+== PROTOCOLS ==
+===============
+
+
+      Client I Server         +-planner-+
+             I                |         |
+             I                |         |
+             I                |         |                     ______
++-amandad-+  I                |         |                    (______)
+|         |  I                |         |                    |amdump|
+|         |  I                |         |           all ::::>|      |
+|         |  I                |         |           stderr   |      |
+|         |  I                |         |                    |      |
+|         |  I                |   so    |                    +------+
+|         |  I                +---------+
+|         |  I                    ::                          ______
+|         |  I                    \/                         (______)
+|         |  I                +-driver--+                    | log  |
++---------+  I                |   si    |           all ::::>|      |
+             I                |         |           log      |      |
+             I                |         |                    |      |
++-sendback+  I                |         |                    +------+
+|         |  I                |         |
+|         |  I        ::::::::|         |<::::::
+|         |  I       ::       |         |      ::
+|         |  I      ::   ::::>|         |::::   ::
+|         |  I      ::  ::    |         |   ::  ::
+|         |  I      :: ::     +---------+    :: ::
+|         |  I      :: ::                    :: ::
+|         |  I      :: ::                    :: ::
+|         |  I      :: ::       ______       :: ::
++---------+  I      :: ::      (______)      :: ::
+             I      :: ::      | /tmp |      :: ::
+             I      \/ ::    :>|      |      \/ ::
++-dump----+  I  +-dumper--+ :: +------+    +-taper/r-+    +-taper/w-+
+|         |  I  |   si so | ::             | si so   |    |         |
+|         |  I  |         | ::  ______     |         |    |         |
+|         |  I  |mesgfd   | :: (______)    |         |    |         |
+|       se|::::>|::::::::>|::  | hold |    |         |    |         |
+|         |  I  |     errf|    | disk |    |      p2c|:::>|p2c      |
+|         |  I  |         |    |      |    |      c2p|<:::|c2p      |     ____
+|         |  I  |datafd   | ::>|      |::: |fd       |    |         |   /   \
+|       so|::::>|::::::::>|::  +------+  :>|::::::::>SHDMEM::::::::>|::>|tape|
+|         |  I  |    outfd| ::          :: |         |    |   tapefd|   \ _ /
++---------+  I  +---------+  ::::::::::::  +---------+    +---------+      
+             I
+
+
+server and amandad on client
+============================
+
+XXX - still to be done
+
+
+planner and driver
+==================
+
+Planner interrogates all clients and generates a plan of which disks to
+backup and what dump level to do them at.  The plan is plain text with one
+line per disk to be dumped.  It is piped from planners stdout to drivers
+stdin.  Plan lines come in two flavours:
+
+For total dumps:
+   <host> <disk> <pri> <lev> <size> <time> <deg lev> <deg size> <deg time>
+
+For incremental dumps:
+   <host> <disk> <pri> <lev> <size> <time>
+
+Where:
+   <host>      Host name of client (from disklist file)
+   <disk>      Name of disk (from disklist file)
+   <pri>       Priority of backup (pri from disklist and amanda.conf + days
+                 overdue for total)
+   <lev>       Dump level for dump (0 for total, 1-9 for incremental)
+   <size>      Estimated size (in Kb after compression if requested)
+   <time>      Estimated time for backup (in seconds)
+   <deg lev>   <lev> to use if in degraded mode
+   <deg size>  <size> to use if in degraded mode
+   <deg time>  <time> to use if in degraded mode
+
+
+driver and dumper
+=================
+
+Driver talks via two pipes connected to each dumper's stdin and stdout.  The
+commands and responses are plain text.
+
+Driver can ask dumper to do a dump to a file on the holding disk:
+   FILE-DUMP <handle> <filename> <host> <disk> <level> <dumpdate> <chunksize> <prog> <use> <options>
+or directly to taper:
+   PORT-DUMP <handle> <port> <host> <disk> <level> <dumpdate> <prog> <options>
+or exit at the end of the run:
+   QUIT
+
+If the dump finishes correctly dumper replies with:
+   DONE <handle> [<message>]
+
+If something goes wrong with the dump, dumper can request that the dump be
+retried at a later time with:
+   TRY-AGAIN <handle> [<message>]
+or, for fatal errors, be abandoned with:
+   FAILED <handle> [<message>]
+
+If the holding disk runs out of space (i. e. 'disk full'), dumper will give:
+   NO-ROOM <handle> <missing_size>
+After that, it will issue RQ_MORE_DISK (see below). The driver will correct
+its notion of free diskspace by subtracting <missing_size> from the
+holding disk's alleged size.
+
+If the dumper has used up all of its allocated holding disk space, it will 
+request more with
+   RQ-MORE-DISK <handle>
+and wait for driver to either allocate more diskspace for the dumper and say
+   CONTINUE <filename> <chunksize> <use>
+or just say
+   ABORT
+(see above).
+
+If driver says something that dumper doesn't recognise it responds with:
+   BAD-COMMAND <message>
+
+Where:
+   <handle>    Request ID
+   <filename>  Name of file on holding disk to write dump (see the section
+               'Multiple Holding Disks' below)
+   <port>      Port (of taper) to send dump directly
+   <host>      Hostname of client
+   <disk>      Disk to backup
+   <level>     Dump level to do backup at
+   <prog>      Dump program to use
+   <options>   Options to pass to sendbackup
+   <message>   Error or status message
+   <use>       Amount of diskspace to use on the holding disk given by
+              <filename>
+   <chunksize> Maximum size of a file on the given holding disk
+   <missing_size> Difference between the allocated space and the space
+                 actually used by a dumper when a DISK FULL occurs
+
+
+driver and taper
+================
+
+Driver talks via two pipes connected to taper's stdin and stdout.  The
+commands and responses are plain text.
+
+Driver initialises taper with:
+   START-TAPER <datestamp>
+to which taper replies with:
+   TAPER-OK
+or, for fatal errors, with:
+   TAPER-ERROR [<message>]
+
+Driver can ask taper to to copy a file from the holding disk to tape:
+   FILE-WRITE <handle> <filename> <host> <disk> <level>
+or directly from a dumper:
+   PORT-WRITE <handle> <host> <disk> <level>
+or exit at the end of the run:
+   QUIT
+
+Taper responds to the PORT-WRITE command with:
+   PORT <port>
+which driver should then hand on to dumper in a PORT-DUMP command.
+
+Taper responds to the QUIT command with:
+   QUITING
+
+If the copy to tape finishes correctly taper replies with:
+   DONE <handle> [<message>]
+
+If something goes wrong with the tape, taper can request that the dump be
+retried at a later time with:
+   TRY-AGAIN <handle> [<message>]
+or, for fatal errors, be abandoned with:
+   TAPE-ERROR <handle> [<message>]
+
+If driver says something that taper doesn't recognise it responds with:
+   BAD-COMMAND <message>
+
+Where:
+   <datestamp> Todays date as "yymmdd"
+   <handle>    Request ID
+   <filename>  Name of file (on holding disk) to write dump
+   <port>      Port (of taper) to send dump directly
+   <host>      Hostname of client
+   <disk>      Disk to backup
+   <level>     Dump level to do backup at
+   <message>   Error or status message
+
+
+taper(read) and taper(write)
+============================
+
+There are two parts to taper: the file reader and the tape writer.
+Communication between the two sides is via a bit of shared memory for data
+transfer and two pipes (one in each direction) for synchronisation.
+
+The shared memory area is made up of NBUFS (=20) buffers each of which
+contains a status word and a BUFFER_SIZE (=32*1024) byte data buffer.
+
+The sync pipes are used to transfer a simplistic command sequence:
+
+reader                              writer
+------                              ------
+
+Startup           S<datestamp> --->
+                               <--- S             Start OK
+                               <--- E<messge>     Error
+
+Open tape         O<datestamp><hostname><diskname><level>
+                              --->
+                               <--- O             Opening
+
+Write buffer      W<bufnum>    --->
+                               <--- R<bufnum>     Buffer empty
+                               <--- E<message>    Error
+                               <--- T<message>    Error, try again
+E ack             e            --->
+Protocol error    X            --->
+                               <--- x             X ack
+
+Close tape        C            --->
+                               <--- C<label><filenum><stats>  Closing
+
+Quit              Q            --->
+
+
+Multiple Holding Disks
+======================
+
+(This section was written by Peter Conrad <conrad@opus5.de>)
+
+Since amanda version x.x.x a single dump file may be spread across multiple
+holding disks. Some changes in the driver-dumper protocol have been introduced
+for this, as well as in the allocation of holding diskspace.
+
+1. Before the dump starts, an initial amount of holding diskspace is
+   allocated for the dump. The amount is based on the estimate for the
+   disk.
+2. If there is enough space available on the holding disks a list of holding
+   disks is created. For each holding disk to be used by the dumper, the
+   space to be used by this dumper and the chunksize of that holding disk
+   are noted (and, of course, the name of the holding disk).
+3. This list is turned into an array? of structures containing the values
+   found in step 2. The first set of values is sent to the dumper.
+4. A dumper is responsible for sticking to the given values:
+    - no file created by the dumper may be larger than the corresponding
+      chunksize
+    - on any given holding disk, no more than 'use' KBytes of diskspace may
+      be used.
+5. a) When all allocated diskspace has been used and the dump still hasn't
+      finished, the dumper may request more space from the driver. The driver
+      can either send a filename and additional size to be used, possibly on
+      a different hodling disk, or tell the dumper to abort the dump.
+   b) When the disk currently in use by the dumper runs full the dumper
+      will tell the driver about this situation. The driver will react like
+      in step a), but it will correct its notion of free diskspace.
+6. If the driver supplies another list of holding disks (not necessarily as
+   much as the dumper requested), the dumper interprets the given 'use' values
+   as *additional* diskspace it may use.
+   Continue at 4.
+
+The protocol between driver and taper didn't need to be modified, because
+each chunk of a dump contains the full pathname of the succeeding chunk.
+
diff --git a/docs/KERBEROS b/docs/KERBEROS
new file mode 100644 (file)
index 0000000..b2c5204
--- /dev/null
@@ -0,0 +1,76 @@
+
+Amanda 2.4.0 - KERBEROS v4 SUPPORT NOTES
+
+Note that kerberos 5 isn't supported.  [yet]
+
+NOTE:  encrypted dumps are rumored not to work in the 2.4.0b4 beta 
+       release of amanda.  Hopefully they'll be fixed by the 2.4.0 
+       full release.
+
+0. GETTING THE SOURCE FILES
+
+The Kerberos-related Amanda source code is available in a separate,
+export restricted, package.  US sites can follow the instructions in
+KERBEROS.HOW-TO-GET on ftp.amanda.org in the /pub/amanda directory.
+
+1. CONFIGURATION
+
+The configure script defaults to:
+
+#  define SERVER_HOST_PRINCIPLE "amanda"
+#  define SERVER_HOST_INSTANCE  ""
+#  define SERVER_HOST_KEY_FILE  "/.amanda"
+
+#  define CLIENT_HOST_PRINCIPLE "rcmd"
+#  define CLIENT_HOST_INSTANCE  HOSTNAME_INSTANCE
+#  define CLIENT_HOST_KEY_FILE  KEYFILE
+
+#  define TICKET_LIFETIME       128
+
+you can override these with configure options if you so desire, with:
+
+    --with-server-principal=ARG    server host principal  [amanda]
+     --with-server-instance=ARG     server host instance   []
+     --with-server-keyfile=ARG      server host key file   [/.amanda]
+     --with-client-principal=ARG    client host principal  [rcmd]
+     --with-client-instance=ARG     client host instance   [HOSTNAME_INSTANCE]
+     --with-client-keyfile=ARG      client host key file   [KEYFILE]
+     --with-ticket-lifetime=ARG     ticket lifetime        [128]
+
+The configure script will automatically include kerberos if you
+followed the directions in step 0.  It'll search under /usr/kerberos/lib,
+/usr/cygnus/lib, /usr/lib, and /opt/kerberos/lib for libkrb.a.
+(in that order) for the kerberos bits.  If it finds them, kerberos
+support will be added in, if it doesn't, it won't.  If the kerberos
+bits are found under some other hierarchy, you can specify this
+via the --with-krb4=DIR, where DIR is where the kerberos bits live.
+It'll look under the 'lib' directory under this hierarchy for
+libkrb.a.
+
+2. INSTALLATION
+
+The kerberized Amanda service uses a different port on the client hosts.
+The /etc/services line is:
+
+    kamanda      10081/udp
+
+And the /etc/inetd.conf line is:
+
+    kamanda dgram udp wait root /usr/local/libexec/amanda/amandad amandad -krb4
+
+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 amanda.
+
+3. CONF FILE
+
+With KRB4_SECURITY defined, there are two new dumptype options:
+
+       krb4-auth       use krb4 auth for this host 
+                       (you can mingle krb hosts & bsd .rhosts in one conf)
+       kencrypt        encrypt this filesystem over the net using the krb4
+                       session key.  About 2x slower.  Good for those root
+                       partitions containing your keyfiles.  Don't want to
+                       give away the keys to an ethernet sniffer!
diff --git a/docs/LABEL.PRINTING b/docs/LABEL.PRINTING
new file mode 100644 (file)
index 0000000..3d91fdb
--- /dev/null
@@ -0,0 +1,51 @@
+New Feature
+-----------
+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 always has.
+
+Labels provided
+---------------
+The author has provided label templates for the following tape types.
+These are pretty generic labels, and should be easy to customize for
+other tape types. Others are encouraged to do so.
+
+exabyte 8mm tapes
+dat 4mm tapes
+DLT tapes (in progress).
+
+
+History
+-------
+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 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.
+
+Our hope in adding this feature is that others find it as useful as
+we have.
+
+How it works
+------------
+The majority of the changes are in reporter.c. Just as you might run
+the reporter by itself to see what the report will (or did) look like
+with a logfile. When the reporter prints out the report, the postscript
+label template is copied, and the successful machines, partitions, and
+dump levels are appended to this. The output either goes to
+/tmp/reporter.out.ps (when running in testing mode) or through a pipe
+to the printer (default printer, if an alternate "printer" is not
+specified).
+
diff --git a/docs/MULTITAPE b/docs/MULTITAPE
new file mode 100644 (file)
index 0000000..5475968
--- /dev/null
@@ -0,0 +1,136 @@
+
+MULTITAPE SUPPORT IN AMANDA 2.2
+
+Draft 1 - jds 3/29/94
+
+1. 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 handle the following:
+
+       - output of amdump run goes to more than one tape
+       - a single dump file can straddle two tapes
+       - more than one amdump run can be done in a single day
+       - planner should not care how many runs per cycle occur
+
+And later:
+
+       - multiple runs of amdump can go onto one tape (eg an append mode)
+       - any dump files from a previous run that are on the holding disk
+         are written to tape in this run (eg eliminate amflush)
+       - taper write to multiple tape drives simultaneously
+
+
+2. NEW PLANNER ALGORITHM
+
+2.1 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 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 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
+
+Where the times A and B are in seconds since the Unix epoch, and 86400 is
+the number of seconds per day.  This rounds a 2.49 day difference down to 2
+days, and a 2.5 day difference up to 3 days.  No, Olafur, Unix time does
+not handle leap seconds.  Give me a break. :-)
+
+2.2 FULL BACKUPS
+
+The first thing planner does is calculate when each filesystem is due for a
+full backup.  This is trivial for normal backups:
+
+       full_is_due = days_diff(<time of last full>, <curtime>) >= dumpcycle
+
+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 tell whether the full backup was actually done or when it was
+done:
+
+       if(skip-full) {
+               if(full_is_due)
+                       <time of last full> += dumpcycle;
+               if(days_diff(<time of last full>, <curtime>) == 0)
+                       skip the filesystem on this run;
+               else
+                       do an incremental dump of this filesystem;
+       }
+
+
+2.3 SCHEDULE BALANCING
+
+The "runtapes" parameter tells planner how many tapes it should plan to use
+each run.  It multiplies this by the tape length to get the size available
+for the run.  (NOTE: later amend this size if appending to tapes, or if
+there are dumps on the holding disk waiting to be flushed).  Other than the
+size calculation, planner doesn't really care how many tapes will be
+written to.
+
+The fundamental problem with attempting to balance the schedule is that we
+no longer know how many amdump runs will be done in a full cycle.  The
+number may change from cycle to cycle if there are extenuating
+circumstances.
+
+So, planner must guess at how many runs will be done in one cycle, by
+looking at the information for the last cycle, or, if this is the first
+cycle, assuming one run for each day in the dump cycle.
+
+2.4 OVERWRITE DETECTION
+
+When can a tape be overwritten, considering that it might have old dumps on
+it?  We want to be able to warn when full dumps are going to be
+overwritten, but given the possibility of old files on the tape, how can we
+know when the tape is no longer needed?  I think we can get this when going
+through the info file, considering each full dump and what tape it is on.
+Make sure we correctly handle stale information.
+
+
+3. TAPER ALGORITHM
+
+3.1 CHOOSING A TAPE
+
+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 TAPE.CHANGERS).
+
+3.2 END OF TAPE HANDLING
+
+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.
+
+Now, Taper needs to switch to a new tape when the current tape has filled
+up.  The tape is considered full when taper gets a write error.  This will
+most likely occur in the middle of writing a (potentially large) backup
+file, perhaps even from a direct-to-tape socket, so there is no possibility
+of starting the backup file over again on the next tape, it must start from
+where it left off, rewriting the block that got the error on the next tape.
+
+To insure correct operation, the file header of the continued file should
+contain an indication that it is a continuation, and at what offset.
+amrestore of course needs to be aware of this scheme and handle it
+correctly, perhaps by double-buffering internally.  XXX provide more alg
+details here, or just leave it with the general idea?
+
+3.3 TAPE FORMAT CHANGES
+
+We need to specify the sequence number of the tape in the run,  in the tape
+header file.  The file header block specifies whether it is a continuation
+file or not.
+
+3.4 TAPELIST FILE CHANGES
+
+The lines in the tapelist file should contain the sequence number of the
+tape in its run, as well as the amount of data written on the tape, and
+perhaps whether or not the end of tape was reached.
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644 (file)
index 0000000..8a18ed3
--- /dev/null
@@ -0,0 +1,31 @@
+## Process this file with automake to produce Makefile.in
+pkgdata_DATA = \
+       DUMPER-API              \
+       EXCLUDE                 \
+       FAQ                     \
+       HOWTO-AFS               \
+       HOWTO-CYGWIN.html       \
+       HOWTO-FILE-DRIVER       \
+       INDEXING                \
+       INSTALL                 \
+       INTERNALS               \
+       KERBEROS                \
+       LABEL.PRINTING          \
+       MULTITAPE               \
+       PORT.USAGE              \
+       RAIT                    \
+       RESTORE                 \
+       SAMBA                   \
+       SECURITY                \
+       SYSTEM.NOTES            \
+       TAPE.CHANGERS           \
+       TAPETYPES               \
+       UPGRADE                 \
+       VTAPE-API               \
+       WHATS.NEW               \
+       WISHLIST                \
+       YEAR2000                \
+       ZFTAPE                  \
+       chg-scsi.notes
+
+EXTRA_DIST = $(pkgdata_DATA)
diff --git a/docs/Makefile.in b/docs/Makefile.in
new file mode 100644 (file)
index 0000000..9590c70
--- /dev/null
@@ -0,0 +1,454 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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@
+
+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 = :
+host_triplet = @host@
+subdir = docs
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in INSTALL
+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 =
+SOURCES =
+DIST_SOURCES =
+am__installdirs = "$(DESTDIR)$(pkgdatadir)"
+pkgdataDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(pkgdata_DATA)
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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@
+pkgdata_DATA = \
+       DUMPER-API              \
+       EXCLUDE                 \
+       FAQ                     \
+       HOWTO-AFS               \
+       HOWTO-CYGWIN.html       \
+       HOWTO-FILE-DRIVER       \
+       INDEXING                \
+       INSTALL                 \
+       INTERNALS               \
+       KERBEROS                \
+       LABEL.PRINTING          \
+       MULTITAPE               \
+       PORT.USAGE              \
+       RAIT                    \
+       RESTORE                 \
+       SAMBA                   \
+       SECURITY                \
+       SYSTEM.NOTES            \
+       TAPE.CHANGERS           \
+       TAPETYPES               \
+       UPGRADE                 \
+       VTAPE-API               \
+       WHATS.NEW               \
+       WISHLIST                \
+       YEAR2000                \
+       ZFTAPE                  \
+       chg-scsi.notes
+
+EXTRA_DIST = $(pkgdata_DATA)
+all: all-am
+
+.SUFFIXES:
+$(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  docs/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  docs/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
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+install-pkgdataDATA: $(pkgdata_DATA)
+       @$(NORMAL_INSTALL)
+       test -z "$(pkgdatadir)" || $(mkdir_p) "$(DESTDIR)$(pkgdatadir)"
+       @list='$(pkgdata_DATA)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(pkgdataDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+         $(pkgdataDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgdatadir)/$$f"; \
+       done
+
+uninstall-pkgdataDATA:
+       @$(NORMAL_UNINSTALL)
+       @list='$(pkgdata_DATA)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f '$(DESTDIR)$(pkgdatadir)/$$f'"; \
+         rm -f "$(DESTDIR)$(pkgdatadir)/$$f"; \
+       done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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 $(DATA)
+installdirs:
+       for dir in "$(DESTDIR)$(pkgdatadir)"; 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:
+       -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-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgdataDATA
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-pkgdataDATA
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-libtool distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-exec install-exec-am \
+       install-info install-info-am install-man install-pkgdataDATA \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       uninstall uninstall-am uninstall-info-am uninstall-pkgdataDATA
+
+# 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/docs/PORT.USAGE b/docs/PORT.USAGE
new file mode 100644 (file)
index 0000000..70ae277
--- /dev/null
@@ -0,0 +1,201 @@
+=================================
+How Amanda uses UDP and TCP ports
+
+John R. Jackson (jrj@purdue.edu)
+8-Aug-2001
+=================================
+
+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.
+
+When a process on the tape server wants to talk to a client, it creates
+a UDP socket and binds it to a port on its side, then sends the packet
+to the well known amandad service port on the client.  Because security
+information is passed, the port bound on the connecting (tape server)
+side must be privileged (less than 1024).  This "proves" to amandad
+whoever is connecting is running as root, and therefor is trustworthy
+(there are all sorts of issues with the validity of this "trust" that
+are beyond the scope of this document).
+
+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 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 port numbers back to dumper in a UDP message.
+Then dumper creates and binds TCP sockets on its side and connects to
+the waiting sendbackup.
+
+Because sendbackup does not run as root on the client, it cannot allocate
+privileged TCP ports to listen on.  The dumper process is setuid root
+and could bind privileged ports on its side (it currently does not),
+but because sendbackup does not care what port connects back to it (it
+assumes the only process that could have knowledge of the port numbers
+to use is dumper), it does not check the peer (connecting) port number.
+
+===================
+TCP port allocation
+===================
+
+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 fails ...
+
+  * try for a privileged port (512 .. 1023).  If that fails ...
+
+  * get any available port.
+
+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 fails ...
+
+  * get any available port.
+
+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 aborted.
+
+This sequence is implemented in stream_client_privileged().
+
+The stream_server() routine is used in two ways:
+
+  * taper to set up direct to tape communication with dumper on localhost.
+
+    If a user TCP port range is defined, it needs to be unprivileged
+    because taper is not running as root.
+
+  * sendbackup to set up a transfer with its dumper.
+
+    If a user TCP port range (--with-tcpportrange) is defined, it needs
+    to be unprivileged because sendbackup is not running as root.
+
+    A user TCP port range needs to be large enough for three ports
+    (data, message and index) times the number of simultaneous backups
+    the client may be asked to perform ("maxdumps" in amanda.conf).
+
+The stream_client() routine is used in two ways:
+
+  * dumper to connect to taper for a direct to tape operation.  Except
+    for making sure what is connecting is not (ftp) port 20 (a common
+    attack entry point), taper does not pay any attention to the source
+    (dumper) port number.
+
+  * dumper to connect to sendbackup on a client.  Again, except for
+    port 20, sendbackup does not care what port the request comes from.
+
+    If a user TCP port range (--with-tcpportrange) is defined, it needs to
+    be unprivileged because dumper is not running as root (at this point).
+
+    A user TCP port range needs to be large enough for two ports (one
+    to sendbackup on the client, and possibly one to taper) times the
+    number of dumpers ("inparallel" in amanda.conf).
+
+The stream_client_privileged() routine is used in one way:
+
+  * amrecover to connect to amindexd and amidxtaped.
+
+    Because security information is passed, amindexd/amidxtaped (via
+    security_ok() in security.c) insist the other end (amrecover) be
+    bound to a privileged port.
+
+=================================================
+User TCP port range (--with-tcpportrange) summary
+=================================================
+
+Pick the max of (2 * inparallel) and (3 * largest maxdumps).  Allocate
+at least that many ports in the unprivileged (1024 or larger) range.
+Stay away from other well known ports (e.g. in your /etc/services file)
+or account for their 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 by dgram_bind():
+
+  * try for the user UDP port range (--with-udpportrange), if defined.
+    If that fails ...
+
+  * try for a privileged port (512 .. 1023).  If that fails ...
+
+  * 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.
+
+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 amanda.conf) and each needs its own port.
+
+=================================================
+User UDP port range (--with-udpportrange) summary
+=================================================
+
+Allocate at least "inparallel" many ports in the privileged (1023 or
+smaller) range.  Stay away from other well known ports (e.g. in your
+/etc/services file) or account for their potential use by making the
+portrange larger.
+
+=================
+Firewalls and NAT
+=================
+
+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-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 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 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 should not be a problem -- it's just like running ftp or telnet.
+But from the outside, NAT will have to know where the amindexd/amidxtaped
+services are and allow them through (much like ftp or telnet daemons).
+Since they are on known port numbers, the user TCP port range is not
+an issue.
+
+A user TCP port range is probably not important in the case of dumper
+and taper talking to each other since only the one machine (localhost)
+is involved and so it does not go through a firewall.  But I could be
+wrong, especially if NAT is involved.
+
+The details of how you configure a specific firewall or NAT are beyond the
+scope of this document (although examples would be welcome).  You need
+to read up on the documentation that comes with them.
diff --git a/docs/RAIT b/docs/RAIT
new file mode 100644 (file)
index 0000000..f9a3869
--- /dev/null
+++ b/docs/RAIT
@@ -0,0 +1,109 @@
+RAIT (Redundant Array of Inexpensive Tape) Support
+
+Author: Marc Mengel<mengel@fnal.gov>.  
+
+Currently it is only integrated with the chg-manual changer script; 
+collaboration on integrating it with the other tape changers is needed. 
+
+What is a RAIT?
+
+RAIT is an acronym for Redundant Array of Inexpensive Tapes, where
+data is striped over several tape drives, with one drive writing 
+an exclusive-or-sum of the others which can be used for error
+recovery.  Any one of the data streams can be lost, and the data
+can still be recovered.  
+
+This means that a 3-drive RAIT set will
+write 2 "data" streams and one "parity" stream, and give you
+twice the capacity, twice the throughput, and the square of the 
+failure rate (i.e. a 1/100 failure rate becomes 1/10,000, since
+a 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.
+
+Using a RAIT:
+
+If you have several tape devices on your system 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"
+       +------------------------------------
+which means that /dev/rmt/tps0d4n, /dev/rmt/tps0d5n, and /dev/rmt/tps0d6n
+are to be treated as a RAIT set.  You can now mount three tapes, and
+label them with amlabel, etc.
+
+
+Also, you want to create a new tape-type entry, which lists an n-drive
+RAIT set, for this RAIT-set.  So if you were using an entry like:
+       +------------------------------------
+       | define tapetype EXB-8500 {
+       |     comment "Exabyte EXB-8500 drive on decent machine"
+       |     length 4200 mbytes
+       |     filemark 48 kbytes
+       |     speed 474 kbytes
+       | }
+       +------------------------------------
+You would want to make a new one like:
+       +------------------------------------
+       | define tapetype EXB-8500x3 {
+       |     comment "Exabyte EXB-8500 3 drive stripe on decent machine"
+       |     length 8400 mbytes
+       |     filemark 200 kbytes
+       |     speed 948 kbytes
+       | }
+       +------------------------------------
+and change your tapetype entry to:
+       +------------------------------------
+       | tapetype EXB-8500x3
+       +------------------------------------
+To tell amanda about the multiple drive set.
+
+To use other than 3 or 5 tape RAIT sets, you need to change the blocksize
+in the tapetype to be divisble by the number of data stripes in your
+RAIT set (i.e. the number of devices minus one).
+
+Blocksizes and Performance:
+
+For better performance, and to get more flexibility with tape stripes,
+you want to build amanda with a very large maxtapeblocksize, something
+like:
+    ./configure --with-maxtapeblocksize=640
+Then you can do something like:
+       +------------------------------------
+       | tapedev = "rait:/dev/rmt/tps0d{4,5,6,7}n"
+       ...
+       | tapetype DLT7000x4
+       ...
+       | define tapetype DLT700x4 {
+       |     comment "Exabyte DLT 4 drive stripe on decent machine"
+       |     length 115167 mbytes
+       |     filemark 120 kbytes
+       |     speed 4482 kbytes
+       |     blocksize 384 kbytes
+       | }
+       +------------------------------------
+which will give you 128k physical blocks on the tape; more generally for
+an n-tape stripe, you want (n-1)*32 kbytes for a tape that likes
+32k physical blocks, or (n-1)*128 kbytes for a tape that likes
+bigger blocks.
+
+Hardware Compression:
+the last stripe is the xor stripe, it is likely to compress poorly
+relative to the other data stripes if you use hardware compression.
+
+Disaster Recovery:
+
+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 recovery from RAIT tape-sets.
diff --git a/docs/RESTORE b/docs/RESTORE
new file mode 100644 (file)
index 0000000..12c2464
--- /dev/null
@@ -0,0 +1,193 @@
+This document was originally written by Daniel Moore
+<dmoore@jeffco.k12.co.us>, on Jan 12, 1998.  Substantially rewritten by
+Alexandre Oliva <oliva@dcc.unicamp.br>.  Additional corrections and
+additions from Murf <jam@philabs.research.philips.com> and Ralf Fassel
+<ralf@atg.venture.de>.  It 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 restore individual files.
+
+Also, this text does not cover amrecover, a program that provides a
+text user interface similar to interactive restore (restore -i), but
+it allows you to select individual files to recover and automatically
+determines the tapes where they were stored.  The backups must be
+performed with the `index' option enabled for this to work.
+
+I considered 6 cases.
+1)  Client machine fails, non-system critical.
+2)  Client machine fails, system critical disk.
+3)  Server machine fails, non-system critical, non-amanda disk.
+4)  Server machine fails, system critical, non-amanda disk.
+5)  Server machine fails, non-system critical, amanda disk, with db.
+6)  Server machine fails, non-system critical, amanda disk, with binaries.
+
+The server machine (machine Aaron) is solaris, the client machine 
+(machine Barney) is sunos.
+
+Cases:
+
+1)  Client machine fails, non-system critical. 
+Example: /home fails on Barney.
+
+First, use amadmin to find the tapes most recently used to backup the 
+partition.
+
+amadmin <config> info Barney '/home$'
+
+Current info for Barney /home:
+  Stats: dump rates (kps), Full:   41.1,  33.1,  38.8
+                    Incremental:    9.5,   2.1,  24.7
+          compressed size, Full:  63.1%, 54.0%, 52.9%
+                    Incremental:  43.7%, 15.5%, 47.8%
+  Dumps: lev datestmp  tape             file   origK   compK secs
+          0  19971223  Barney01           16  329947  208032 5060
+          1  19980108  Barney16            8    1977     864   91
+          2  19971222  Barney06            7    1874     672   83
+          3  19970926  Barney03           11   12273    3040  211
+
+This tells us that we will need two tapes to do a full restore
+(Barney01, Barney16).  Note that, even if Barney06 and Barney03 are
+listed, they are actually older than the full backup, so they should
+not be used to restore any data.
+
+Log into Barney.  Cd to the /home directory.  Insert the tape with the 
+level 0 dump on it into the tape drive of Aaron.
+
+Become super-user in the client host and run (replace <amanda> with
+the username under which amanda runs):
+
+rsh -n -l <amanda> Aaron amrestore -p /dev/rmt/0cn Barney '/home\$' |
+restore -ivbf 2 -
+
+This requires client root to have login access to <amanda>@Aaron, with
+a .rhosts entry (.amandahosts won't do).  If you use ssh, you may be
+able to type a password in order to be authenticated.  Another
+alternative is to start the operation in the server, and rsh to the
+client.  You should be the amanda user or root in the tape server and run:
+
+amrestore -p /dev/rmt/0cn Barney '/home$' |
+rsh Barney -l root /usr/etc/restore -ivbf 2 -
+
+If you don't want to use rsh at all, you may run:
+
+amrestore /dev/rmt/0cn Barney '/home$'
+
+This should create a file whose name contains the hostname, directory
+name, dump level and dump date of the backup.  Now you have to move
+this file to the client somehow: you may use NFS, rcp, ftp, floppy
+disks :-), whatever.  Suppose you rename that file to `home.0'.  Then,
+on the client, you should become root and run:
+
+restore -ivbf 2 home.0
+
+Repeat one of these steps, incrementing the level of the dump, until
+there are no more available backups.
+
+
+2)  Client machine fails, system critical disk.
+Example: / fails on Barney.
+
+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.
+
+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.
+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.
+An example: /opt on Aaron
+
+If the disk that 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 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.
+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 
+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 to explore most fully, because this seems the most likely to occur.
+
+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).
+
+b) Look over the copy of the output of 'amadmin <config> export', and find
+out which tapes /usr/local was backed up on.
+
+c) Grab the tapes that /opt was backed up on, and stick the level 0 into 
+the drive.  cd to /usr/local.
+
+d) Skip the first record, which is just the tape header, by using the
+appropriate tape command.
+
+mt -f /dev/rmt/0cn fsf 1
+
+e) Now you want to start looking for /usr/local on this tape.
+
+dd if=/dev/rmt/0cn bs=32k skip=1 | gzip -d | /usr/sbin/ufsrestore -ivf -
+This command gives us an interactive restore of this record, including
+telling us what partition, what host, and what level the backup was.  The
+gzip -d portion of the pipe can be omitted if there was no compression. 
+
+f) If you don't find /usr/local on the first try, quit ufsrestore, and move 
+forward one record.
+mt -f /dev/rmt/0cn fsf 1
+and try the dd/restore command shown above.  Do this until you find /opt 
+on the disk.
+
+Another possibility: quick and dirty tape index in case you don't know
+which partition /usr/local was on: (from ralf@atg.venture.de)
+
+#!/bin/sh
+TAPEDEV=</dev/nrtape>
+while mt -f $TAPEDEV fsf 1 ; do
+  dd if=$TAPEDEV bs=32k count=1 | head -1
+  sleep 1
+done
+
+Example output:
+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
+
+g) Restore the amanda binaries (what else do you need??), and then bail 
+out of ufsrestore.  You can use amrestore, as in Scenario 3.
diff --git a/docs/SAMBA b/docs/SAMBA
new file mode 100644 (file)
index 0000000..1e3adee
--- /dev/null
@@ -0,0 +1,177 @@
+Notes for adding PC hosts to the Amanda backup system.
+
+============
+Installation
+============
+
+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
+
+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:
+
+  http://www.amanda.org/patches.html
+
+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.
+
+This problem may also occur if you have large (>2GB) shares with Samba
+prior to 2.0.4.  In this case, apply samba-largefs.patch from the Amanda
+patches page.
+
+After building and installing samba with the selected patches, Amanda
+must be configured with smbclient support.  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
+
+=====
+Setup
+=====
+
+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 disklist file.  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
+disklist entry.
+
+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 the user does not have full access, incremental backups
+will not work and the whole share will be backed up every time (Archive
+bits are never reset).
+
+File /etc/amandapass must be created by hand.  It contains share name
+to user name, password and workgroup mapping.  Each line consists of two
+or three whitespace separated fields:
+
+  * Share name followed by optional directory.
+  
+    Must use forward slashes (/), not backslashes (\).
+
+    Must match the disklist entry exactly (case sensitive).
+
+    May be asterisk (*) to match all remaining shares for this Samba
+    server.  The first match in the file is used, so specific entries
+    must be listed first.
+
+    The directory is appended to the share name as full M$ network path.
+    Like //thepc/c$/mydir . No blanks in directory!
+
+  * User name and password.
+
+    Separated by a percent sign (%).  See the description of the -U
+    option to smbclient.
+
+    No whitespace allowed in either the user name or password.
+
+  * Workgroup (optional).
+
+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'.  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.
+
+The entry in the disklist file is:
+
+pcserver       //thepc/backupc         nocomp-user-gnutar
+
+^ samba installed unix host
+                ^ pc host and share name
+                                       ^ dumptype must include the tar option
+
+In /etc/amandapass on the machine 'pcserver':
+
+//thepc/backupc                bozo%f00bar
+
+If smbclient requires a workgroup specification (-W), you may add it as
+a third argument in /etc/amandapass line:
+
+//thepc/backupc                bozo%f00bar     NTGROUP
+
+This will cause smbclient to be invoked with -W NTGROUP.
+
+An example dumptype in amanda.conf would be:
+
+define dumptype nocomp-user-gnutar {
+    program "GNUTAR"
+    comment "user partitions dumped with tar and no compression"
+    options no-compress
+    priority medium
+}
+
+Essentially, the disklist entry is a 'pseudo-disk' which contains all the
+relevant information needed by the smbclient program to backup the disk,
+but in an Amanda compatible way.
+
+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.
+
+==============
+Bugs and notes
+==============
+
+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 backing up (restoring, actually) system disks.
+
+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.
+
+It seems impossible to detect when a per-user based login fails, e.g. the
+username doesn't have sufficient access.  It connects but cannot see any
+files (e.g. backups do nothing).  The selfcheck code isn't particularly
+robust in this area either, so you may get no warnings when a disk isn't
+being backed up.  Just check to see that level 0 dumps are bigger than
+64K, otherwise it means the backup was empty.
+
+The estimate and totals are probably a bit off since tar pads to the
+nearest 512 bytes after each file (i think).  Not sure how much of a
+problem this is.
+
+Smbclient only supports excluding a single file from the command line,
+not a file of patterns like GNU tar.  So "exclude" is supported from a
+dumptype but not "exclude list".
+
+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 ignored).  Things are done this way because
+doing a simulated dump to /dev/null, like other dump programs, would
+take forever with current implementations of Samba.
+
+If you compile with smbclient support, gnutar support is automatically
+enabled.  If you aren't using the gnutar part, you may get warnings
+about the availability of /usr/local/bin/gtar (or whatever it was
+compiled with).  These may safely be ignored, unless you enable index
+generation for those filesystems.
+
+Original text by:
+Michael Zucchi
+School of Computer and Information Science
+University of South Australia
+M.Zucchi@CIS.UniSA.Edu.Au
+
+Updated by:
+John R. Jackson
+Purdue University Computing Center
+jrj@purdue.edu
diff --git a/docs/SECURITY b/docs/SECURITY
new file mode 100644 (file)
index 0000000..2b7c735
--- /dev/null
@@ -0,0 +1,48 @@
+AMANDA TEAM RESPONSE TO CPIO Security Notice Issue 11:
+
+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:
+
+       ftp://ftp.amanda.org/pub/amanda/amanda-2.4.0b5.tar.gz
+
+Here's some more information about the amrecover problem to supplement the
+information given in the CPIO Security Notice:
+
+VERSIONS AFFECTED:
+
+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 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 be disabled by:
+
+- removing amandaidx and amidxtape from /etc/inetd.conf
+
+- restarting 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
+upgrading to the new release as soon as practicable.
+
+ACKNOWLEGMENTS:
+
+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 for any contribution that helps us achieve and sustain critical
+mass for improving Amanda.
diff --git a/docs/SYSTEM.NOTES b/docs/SYSTEM.NOTES
new file mode 100644 (file)
index 0000000..a8277f7
--- /dev/null
@@ -0,0 +1,305 @@
+Amanda 2.4 - System-Specific Installation Notes
+
+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 amanda-hackers@amanda.org,
+after checking that they are not known/fixed problems in the amanda
+patches page: http://www.amanda.org/patches.html
+
+---------------------------------------------------------------------------
+Solaris 2.6
+-----------
+
+You may have compilation errors on statfs.c if you're running, on a
+Solaris 2.6 host, a gcc that was not build on a Solaris 2.6 host.
+This happens because gcc stores fixed copies of some Solaris header
+files on an internal directory.  You 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.
+
+---------------------------------------------------------------------------
+Trusted Solaris
+---------------
+
+According to Julian Stevens <julian.stevens@baedsl.co.uk>, the format
+of inetd.conf 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 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
+------
+
+The Ultrix dump program contains an explicit check that it is being
+run by root.  This defeats the usual practice of a non-root "operator"
+userid for dumps.  For this reason, the rundump program (a setuid-root
+wrapper for dump) is enabled by default.  If you find rundump is not
+necessary for you, just configure --without-rundump.
+
+
+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 <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/nul',
+for instance, and link /dev/nul to /dev/null.  Note that the chosen
+file name must be exactly 8 bytes long, otherwise you'll break the
+restore program.  A nice one-liner perl script by Martyn Johnson will
+do the trick (make sure you 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 to need gcc or egcs.
+
+---------------------------------------------------------------------------
+HP/UX
+-----
+
+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.
+
+
+If `configure' complains about not finding `lex', you'll have to get
+`flex' installed.  Look for its URL in docs/INSTALL.
+
+
+If you use logical volumes, you may refer to mountpoints or full
+device pathnames instead of device names in the disk list file.
+
+
+According to Stan Brown <stanb@awod.com>, amverify won't work with
+HP/UX's 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 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.
+
+
+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>
+
+---------------------------------------------------------------------------
+Linux
+-----
+
+Linux hosts intended to back up efs partitions with dump should
+install the dump package, as it is not installed by default on most
+Linux distributions.  It is possible to find compiled versions of dump
+on most Linux sites and CD-ROMs.
+
+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.
+
+
+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 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, have modified dump so that it stores dumpdates in
+/var/lib.  If this is your case, you should create a link to it in
+/etc.  Suggested by David Wolfskill <dhw@whistle.com>
+
+---------------------------------------------------------------------------
+Digital Unix 4
+--------------
+
+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 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/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 HAVE_DUMP_ESTIMATE in
+config/config.h; if you prefer to have incorrect estimates for SAMBA
+backups, follow the instructions in 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.
+
+---------------------------------------------------------------------------
+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.
+
+Sinix port originally by Michael Schmitz <mschmitz@iname.com>.
+
+---------------------------------------------------------------------------
+IRIX (all)
+----------
+
+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 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 system with *all* kernel and scsi rollup
+patches, otherwise you may end up with useless tapes, due to tape
+rewinding after short periods of inactivity.  See
+http://www-viz.tamu.edu/~sgi-faq/ for more details.
+
+
+Some unpatched version of xfsdump are reported as not printing
+estimates.  This causes estimates to take much longer than they had
+to, because backups are always performed twice.  According to Mike
+Acar <mike@kentinfoworks.com>, patch 2333 for IRIX 5.3 and 6.1 will
+fix this problem.
+
+---------------------------------------------------------------------------
+IRIX 6
+------
+
+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.
+
+
+---------------------------------------------------------------------------
+SCO
+---
+
+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.  GNU tar 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.
+
+
+---------------------------------------------------------------------------
+FreeBSD 3.0
+-----------
+
+chg-scsi was not updated to support the new camlib.h-dependent chio.h,
+so chg-scsi will be automatically disabled if camlib.h is found.  You
+may use chg-chio instead.
+
+
+---------------------------------------------------------------------------
+FreeBSD 5.1
+-----------
+
+Nicolas Ecarnot <nicolas.ecarnot@accim.com> discovered that for
+FreeBSD 5.1 (maybe earlier, and surely further), you have to set the
+net.inet.udp.maxdgram TCP/IP variable to 65535.  The default is 9216,
+and this is a problem when trying to backup a large number of clients
+as indicated by errors in during amcheck or the estimate phase.
+
+You can just run the command:
+
+  sysctl net.inet.udp.maxdgram=63535
+
+but this won't last until the next reboot.
+
+To make it permanent, just add this line:
+
+  net.inet.udp.maxdgram=65535
+
+in the /etc/sysctl.conf file.
+
+
+---------------------------------------------------------------------------
+AIX
+-----------
+
+sendsize is reported to coredump on AIX 4.3.3, this is a linking problem,
+try configuring amanda with --disable-shared option.
+
+
+---------------------------------------------------------------------------
+Microsoft Windows
+-----------------
+
+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 docs/SAMBA for more information.
+
+SAMBA may be unable to back up some files due to file locking
+restrictions.  Particularly, paging and registry files usually present
+problems.  Backing up page files is pointless, but registry files are
+quite important to back up.  It is possible to create regular files
+that contain registry information by using the Regback utility, from
+the Windows NT Resource Kit.  Unfortunately, is not part of the
+Windows NT standard distribution, you have to purchase it separately.
+Thanks to Ernie Oporto <ernie_oporto@mentorg.com> for the tip.
diff --git a/docs/TAPE.CHANGERS b/docs/TAPE.CHANGERS
new file mode 100644 (file)
index 0000000..ba53ec5
--- /dev/null
@@ -0,0 +1,791 @@
+AMANDA TAPE CHANGER SUPPORT
+
+Originally by James da Silva <jds@cs.umd.edu>
+Heavily modified by various contributors
+
+1. INTRODUCTION
+
+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 software and hardware possible.
+
+The interface is a bit simplistic and has only had complications added
+when there is a body of field experience.
+
+
+2. SPECIFYING A TAPE CHANGER IN AMANDA.CONF
+
+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 amanda.conf file.  Example entry:
+
+       tpchanger "chg-multi"      # use multi-unit tape changer emulator
+
+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 in libexecdir, and possibly have the version suffix appended
+depending on how 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 configuration file specific to the changer, or be a base name
+of several related changer files.  The changerdev variable may point to
+the /dev entry used to access the changer device.
+
+See the documentation with the specific changer you're interested in to
+see exaclty how these variables are used (if at all).
+
+
+3. DEVICE-SPECIFIC TAPE CHANGER SCRIPT
+
+The tape changer script/program is always from the directory with
+amanda.conf.  It is never passed the configuration name it is running
+on behalf of, but since amgetconf works without a name from the current
+directory, that should be sufficient.
+
+The script/program must support the following commands:
+
+    <tpchanger> -slot <slot-specifier>
+
+               If changer is loaded, unloads the current slot (if
+               different than "slot-specifier") and puts that tape away,
+               then loads the requested slot.  See the next section for
+               the list of valid slot requests.
+
+               Outputs to stdout the slot name and name of the device
+               file to access the tape on success, or a slot name and
+               error text.
+
+               Returns 0 on success.
+
+               Returns 1 on positioning error (eg at bottom of gravity
+               stacker or slot empty).
+
+               Returns 2 any other fatal error.
+               The slot name may be invalid, but must be present.
+               Error message goes to stdout in place of device name.
+
+       Examples:
+               % chg-multi -slot 0
+               0 /dev/nrst8                    # exitcode returned is 0
+
+               % chg-multi -slot 1
+               1 slot 1 is empty               # exitcode returned is 1
+
+               % chg-multi -slot bogus-slot
+               <none> no slot `bogus-slot'     # exitcode returned is 2
+
+
+    <tpchanger> -info 
+
+               Outputs to stdout three or more fields:
+               
+                 * The current slot string (required)
+                 
+                 * The number of slots (required)
+
+                 * 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 it can't, 1 if it can). (optional)
+
+       Examples:
+               % chg-multi -info
+               0 10 1                          # exitcode returned is 0
+
+               % chg-zd-mtx -info
+               0 10 1 1
+
+    <tpchanger> -reset
+
+               Resets the changer to known state and loads the first slot.
+
+               Output and error handling are the same as
+
+                 "<tpchanger> -slot first"
+
+               In the case of a gravity stacker that must be reset
+               by hand, this could be run (via "amtape <conf> reset")
+               to inform the software the stacker is positioned back
+               at the top.
+
+       Examples:
+               % chg-multi -reset
+               0 /dev/nrst8                    # exitcode returned is 0
+
+               % chg-multi -reset
+               0 slot 0 is empty               # exitcode returned is 1
+
+               % chg-multi -reset
+               0 tape-changer not responding   # exitcode returned is 2
+
+    <tpchanger> -eject
+
+               Unloads the current slot (if loaded) and puts that tape away.
+
+               Output and error handling are the same as the -slot command.
+
+               Note that a tape may or may not be loaded when this command
+               completes, depending on the hardware.
+
+       Examples:
+               % chg-multi -eject
+               0 /dev/nrst8                    # exitcode returned is 0
+
+               % chg-multi -eject
+               0 drive was not loaded          # exitcode returned is 1
+
+The tape changer program MAY support the following commands:
+
+    <tpchanger> -search <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.
+
+       Example:
+               % chg-zd-mtx -search DailySet005
+               5 /dev/nrst8                    # exitcode returned is 0
+
+    <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.
+
+       Example:
+               % chg-zd-mtx -label DailySet006
+               6 /dev/nrst8                    # exitcode returned is 0
+
+
+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.
+
+       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.
+
+       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, perhaps requesting
+       a different slot be loaded.
+
+       Any other exit code is considered fatal and will cause Amanda
+       to stop attempting to talk to the tape changer.
+
+
+4.  SLOT NAMES AND THE "CURRENT" SLOT
+
+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 "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 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 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 meaning as follows:
+
+       current The position of the last loaded tape, as described above
+
+       next    The position after current, wrapping from the last slot to
+               the first.
+
+       prev    The position before current, wrapping from the first slot to
+               the last.
+
+       first   The first slot in the tape rack.
+
+       last    The last slot in the tape rack.
+
+       advance The same as "next" except the next tape may not be loaded if
+               the changer supports advancing to the next slot without
+               putting that tape in the drive.
+
+The current position must be updated even if there is a positioning error
+(such as "empty slot").  This allows amanda to step through the entire tape
+rack by issuing successive "-slot next" positioning commands.
+
+
+5. OPERATOR INTERFACE
+
+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
+
+       amtape <conf> eject
+               Send an eject command to the tape-changer.  Effect is changer
+               specific.
+
+       amtape <conf> reset
+               Send a reset command to the tape-changer.  Effect is changer
+               specific.
+
+       amtape <conf> show
+               Go through the entire tape rack, showing the labels of all 
+               amanda tapes encountered.
+
+       amtape <conf> label <label>
+               Find and load the tape with the specified label
+
+       amtape <conf> taper
+               Perform taper's scan algorithm (see below), loading the tape
+               which would be picked for the next amdump run.
+
+       amtape <conf> clean
+               If a cleaning tape is defined by the changer, load it in
+               the drive and put it away when done.
+       
+       amtape <conf> device
+               Output the current tape device name.
+       
+       amtape <conf> current
+               Display the contents of the current slot.
+       
+       amtape <conf> update
+               Scan the entire tape rack and update the barcode database.
+
+See the amtape(8) man page for more details.
+
+In addition to amtape, amlabel has been modified to allow optionally
+specifying a slot:
+
+       amlabel <conf> <label> [slot <slot-specifier>]
+
+Amcheck looks for the next tape in the rack the same way the taper does.
+If multiple tapes are used in one night, amcheck attempts to find all the
+needed tapes in turn if the tape-changer is random access.  On a one-way
+gravity stacker, amcheck only finds the first tape, since finding the
+subsequent ones would put the first one out of reach of that night's
+amdump run.
+
+Amrestore and amrecover do not yet include any tape changer support
+directly, as amrestore knows nothing about the amanda.conf files or
+server-side databases.  This is a deliberate decision to keep amrestore
+independent, so it can be run from any host with a tape drive, even
+if the original tape server host is down.  To use amrestore in a
+tape-changer environment, use amtape to find the right tape, then run
+amrestore giving the resulting tape device name.
+
+
+6. HOW AMDUMP INTERACTS WITH THE TAPE CHANGER
+
+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.
+
+Amdump uses two algorithms, depending on whether the tape changer can go
+backwards in the rack or not.  If multiple tapes are needed in a single
+run, this algorithm is repeated in turn whenever a new tape is required.
+
+Normal tape changers (those that can go backwards):
+
+With a full-access tape changer, Amdump searches the entire rack for the
+preferred tape label.  This tape will usually be found at the current
+or next position, but might be located anywhere.  If the tape is found,
+it is used.  If 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 tape (starting at the current position) that matches the labelstr
+and is not active, regardless of whether it is the preferred tape.
+
+
+7. BUILT-IN TAPE CHANGERS
+
+================================
+chg-multi (formerly chg-generic)
+================================
+
+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.
+
+  - Using a gravity stacker or a real changer configured to sequentially
+    load the next tape when the current one is ejected.  Also supports
+    a changer which cycles to the first tape after loading the last one.
+
+  - Using a changer accessed through several "virtual" tape devices
+    which determine which slot actually gets loaded in the tape drive.
+
+The advantage of this changer script is that you do not need to get into
+the complexity of dealing with a real changer interface.  All the action
+goes through the tape device interface with standard "mt" commands,
+which eases many portability issues.  Many common tape jukeboxes can be
+configured in a sequential or cycle mode.
+
+chg-multi ignores `tapedev' and `changerdev' because `changerfile' may
+specify several tape devices to be used.  A sample configuration file
+may be found in example/chg-multi.conf.
+
+================================
+chg-manual (formerly no-changer)
+================================
+
+This is a poor man's tape changer that requires the backup operator to
+change tapes manually.  It expects `tapedev' in amanda.conf to point to
+a valid tape device, and stores some status data in files whose names
+start with the `changerfile'.  `changerdev' is ignored.
+
+=============================
+chg-mtx (formerly hp-changer)
+=============================
+
+An mtx-based tape changer script.  `changerdev' must specify the tape
+device controlled by the mtx program, and `tapedev' must point to the
+no-rewind tape device to be used.  More than likely, both `changerdev' and
+`tapedev' will reference the same device file.  `changerfile' must specify
+a prefix for status files maintained by this script.  It will maintain
+files named `changerfile'/changer-clean and `changerfile'/changer-access.
+You may have to edit the script to specify which slot contains a cleaning
+tape (cleanslot).
+
+The `mtx' program must support commands such as `-s', `-l' and `-u'.
+If the one you've got requires `status', `load' and `unload', you should
+use chg-zd-mtx instead (see below).
+
+==========
+chg-zd-mtx
+==========
+
+Based on chg-mtx, but modified in order to support the Zubkoff/Dandelion
+version of mtx.  Eric DOUTRELEAU <Eric.Doutreleau@int-evry.fr>, who
+contributed this script, reported that it works on a Solaris/sparc box
+with a HP 1557A stacker.
+
+In addition to the `changerfile'-clean and the `changerfile'-access files,
+it maintains a `changerfile'-slot file that indicates the currently
+loaded slot.
+
+There are lots of comments at the start of the script describing how to
+set it up.
+
+========
+chg-disk
+========
+
+Clone of the chg-zd-mtx, but modified to be applied on local directories
+instead of tapes. This changer emulates a robotic that uses virtual
+tapes instead of real ones, where the virtual tapes are real directories
+on a hard disk.
+
+The directory tree should be:
+slot_root_dir -|
+               |- info
+               |- data -> slot1/
+               |- slot1/
+              |- slot2/
+              |- ...
+              |- slotn/
+
+Where "slot_root_dir" is the tapedev "file:xxx" parameter and "n" the
+tapecycle parameter.
+
+Please refer to the HOWTO-FILE-DRIVER for details of usage.
+
+
+
+
+=======================================================
+chg-scsi-chio (formerly seagate-changer, then chg-chio)
+=======================================================
+
+A C program that relies on scsi tape-changer interfaces.  It may
+either use the tape changer interface specified in chio.h (Gerd Knor's
+SCSI media changer driver, a Linux kernel loadable module), or it may
+use built-in tape changer interfaces available on HPUX, Solaris 2.5,
+IRIX and possibly others, but only the chio and HPUX interfaces are
+currently implemented .  `tapedev' specifies the tape device to be
+used; `changer_dev' is the device used to talk to the kernel module
+(for chio, usually /dev/ch0), and `changerfile' specifies a filename
+in which the current slot number will be stored.
+
+Now there is another way, to get the chg-scsi a little bit more
+flexible.  If you use only one digit in the `tapedev' parameter, the
+chg-scsi expects that 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 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 there is also some stuff for
+cleaning the drives.
+
+In amanda.conf:
+
+tapedev "x"       with x between 0 and 9, selects the configuration to use
+changerfile "filename"            specifies the changer configuration file
+
+In the changer-config-file the following could be set:
+number_configs x       x between 0 and 9       number of configurations
+                                               defined. This should be
+                                               the first parameter in the
+                                               config-file.
+eject  x               x 0 or 1                1 means that the drives need
+                                               an eject command, before the 
+                                               robot can handle the tape.
+sleep  x               x between 0 and MAX_INT specifies the seconds to wait
+                                               before the drive could be used
+                                               after inserting a tape. 5
+                                               should be OK.
+cleanmax x             x some positive int     How many cleanings does a 
+                                               cleaning tape survive
+changerdev  <device>                           The device for the robot
+
+And then there come some configuration sections, separated by the word `config`
+followed by the ordinal of that configuration (0 to 9). In each configuration
+section you should specify:
+
+drivenum x             x between 0 and the number of drives in the library
+                                               This one specifies the drive to
+                                               use with this configuration
+dev    <device>                                The device for the tapedrive
+startuse    x          x between 0 and maximum slotnumber of your library
+                                               Starting here we may use the tapes
+enduse  x              x between start and maximum slotnumber
+                                               This is the last tape we may use
+                                               in this configuration. If we reach
+                                               this one the next will be start..
+statfile <filename>                            Here we remember the last used
+                                               slot for this configuration
+cleancart      x       x between 0 and maximum slotnumber 
+                                               In this slot we find the 
+                                                cleaning tape
+cleanfile <filename>                           Here we will remember how 
+                                               often we used the cleaning tape
+usagecount <filename>                          This points to a file which is
+                                               deleted after cleaning the drive
+                                               e.g. the usagetime of the drive
+                                                                                        
+Comments begin with an '#' until end of line.
+Allowed separators are TAB and SPACE. 
+
+========================================================================
+chg-scsi (new interface, try to drive a robot with direct scsi commands)
+========================================================================
+
+The config and the sysntax is the same as for chg-scsi-chio. New
+is the config type 
+
+emubarcode     1
+
+With this option and the option labelfile chg-scsi will try to create an inventory.
+With this inventory it should be possible to use the search feature for loading tapes.
+
+debuglevel x:y
+
+This option will set the debug level and select for which part debug messages should be sent
+to the debug file. In case of problems you should set it to 9:0
+
+havebarcode 1
+
+This will force the program to read the barcodes, and don not try to figure out if there is an
+barcode reader available.
+
+scsitapedev <devicename>
+
+This device is used to control the tape, read status infos etc.
+
+tapestatus <filename>
+
+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.
+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
+
+Use the mtio ioctl to eject the tape, use only if the standard (1) does
+not work, and send the debug output (/tmp/amanda/chg-scsi.debug) to
+th@ant.han.de
+
+changerident <ident>
+
+With this it is possible to specify which internal driver to use for
+controlling/error handling of the robot
+
+tapeident <ident>
+
+Some as above but for the tape.
+
+
+New command line option:
+-status [all|types|robot|sense|ModeSenseRobot|ModeSenseTape|fd]
+
+<all> will show the result form all options.
+<types> will list the known driver types.
+<robot> will show the status of all elements (tape/robot/slots..)
+<sense> will show the result from a request sense
+<ModeSenseRobot> will show the sense page from the robot
+<ModeSenseTape> will show the sense page from the tape
+<fd> will show the devices which are open, and some info about it.
+
+
+At the moment changer with tape and robot on the same SCSI id (
+but on different luns) will run on the following plattforms
+HP_UX 10.20    
+IRIX 6.x
+Solaris
+Linux
+AIX
+FreeBSD 3.0/4.0
+
+Tape and robot on different IDs run native on
+Linux
+HP-UX 10.20
+Irix 6.x
+FreeBSD
+
+Tape and robot on different IDs with special modules run on:
+
+Solaris        with sst kernel module, which is not any longer needed in solaris 2.8.
+See in the contrib/sst directory
+The configuration on solaris 2.8 with the sgen driver is done by creating
+the file /kernel/drv/sgen.conf
+This file should contain at the beginning the following
+device-type-config-list="changer","sequential"
+
+This will force the driver to attach only to the devices with type either
+changer (the robot) and sequential (the tape).
+Next you must tell the driver on which id it should check for devices
+(tape on id 5, robot on id 6 in this example),
+name="sgen" class="scsi" target=5 lun=0;
+name="sgen" class="scsi" target=6 lun=0;
+
+This will create the 2 device files
+/dev/scsi/sequential/c0t5d0         (scsitapedev option in chg-scsi.conf)
+/dev/scsi/changer/c0t6d0            (changer option in chg-scsi.conf)
+
+So the complete sgen.conf looks like:
+device-type-config-list="changer","sequential
+name="sgen" class="scsi" target=5 lun=0;
+name="sgen" class="scsi" target=6 lun=0;
+
+
+For HP you have to create the special device files for the pass throu
+interface. Check if the ctl driver is installed.
+Example:
+# lsdev -C ctl
+    Character     Block       Driver          Class
+      203          -1         sctl            ctl
+
+Next check on which bus your drives are connected. (ioscan)
+
+with the Character device num form the lsdev and the card instance from
+ioscan create the special file.
+Example:
+mknod /dev/scsi/1 c 203 0x001000
+                          ||||
+                          ||| LUN of device
+                          ||SCSI ID of the device
+                          2 digit instance number from ioscan
+
+On FreeBSD 4.0 the syntax for the device files has changed. Now you
+have to tell chg-scsi the bus:target:lun combination. If you for
+example on your scsi bus 0 target 3 an robot the syntax is
+changerdev 0:3:0
+To get this info you can use the camcontrol command, <camcontrl devlist>
+will give you a list of known devices.
+Don't specify dev and scsitapedev in your chg-scsi.conf !!, this will
+not work.
+
+On Linux you need either sg (generic scsi) as module or it must be compiled
+into the kernel. If the sg driver doses not work try to use the ioctl interface.
+For that you have to undef the LINUX_CHG define in changer-src/scsi-linux.c
+Also you have to change the NORMAL_TIMEOUT in /usr/src/linux/drivers/scsi/scsi_ioctl.c
+from (10 * HZ) to (5 * 60 * HZ).
+On linux it does not run if you are using an aha1542 SCSI controller. The
+driver can not handle the extended request sense.
+
+On IRIX you find the SCSI pass through interfaces for every device in /dev/scsi
+
+chg-scsi has been tested/run with the following devices
+Exabyte 10h and eliant tape
+HP-Surestore 1200e and C1553A tape
+BreeceHill Q2.15 (EXB-120) and DLT7000 tape
+Powerstor L200 and DLT7000 
+ARCHIVE Python 28849-XXX 
+TANDBERG TDS 1420
+ADIC VLS DLT Library
+
+It is now possible with a changer that has barcode reader to load tapes faster.
+Also amdump will find tapes faster. Every time a tape is labeled the information
+in the labelfile will be updated. To initialize the label mapping you can also
+do an amtape config show. This will put the mapping for all tapes in the magazine
+into the mapping file.
+
+For all problems please contact th@ant.han.de. Please include in your
+mail the debug file. (/tmp/amanda/chg-scsi.debug)
+
+
+===========================================================================
+chg-chio (new perl script that replaces the original chg-chio written in C)
+===========================================================================
+
+This script is based on the FreeBSD version of chio, a program to
+communicate with the jukebox.  This script has for the moment only
+been test with FreeBSD and is likely not to work on any other system.
+Let me know if this is the case and send me the output of the chio
+program for your version of chio.
+
+It does not restrict the number of tapes, except that if there is only
+one tape in the juke, it is supposed to be in max_slot and not in slot 1.
+
+[This is the first version of the changer script and I would
+appreciate all comments on it, at nick.hibma@jrc.it.  It has been
+tested only with FreeBSD 2.2.5 and the accompanying chio program.]
+
+==============================
+chg-chs (formerly chs-changer)
+==============================
+
+A tape changer script very similar to chg-multi, that uses the `chs'
+program to change tapes.  As in chg-multi, `tapedev' is ignored.
+`changerfile' names its configuration file, similar to chg-multi.conf.
+`changerdev' will be passed to CHS in a -f command-line switch, unless
+it is set to an empty string or "/dev/null" (watch out for default
+values!)
+
+==============================
+chg-rth (formerly rth-changer)
+==============================
+
+A perl5 script that controls an HPc1553 tape drive via a Peripheral
+Vision Inc. SCSI control subsystem that interprets commands sent on
+the SCSI bus.  It expects `tapedev' to specify the tape device to be
+used.  `changerfile' and `changerdev' are ignored.
+
+==============================
+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 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) 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}")
+
+==============================
+chg-rait
+==============================
+
+A shell script that runs other changers in tandem, and returns
+a rait:{dev1,dev2,...} tape device based on the results of 
+each other changer.  So if you wanted to have 2 stackers
+striped with no parity, and you have chg-mtx support for your
+stackers, you would use the follwing changerfile:
+   nchangers=3
+   tpchanger_1="chg-mtx"
+   changerdev_1="/dev/mtx1"
+   changerfile_1="/some/file1"
+   tapedev_1="/some/dev"
+   tpchanger_2="chg-mtx"
+   changerdev_2="/dev/mtx2"
+   changerfile_2="/some/file2"
+   tapedev_2="/some/dev"
+   tpchanger_3="chg-null"
+   changerdev_3="/dev/null"
+   changerfile_3="/some/file3"
+   tapedev_3="/some/dev"
+
+The third uses the null changer.  The tapedev_n entries are only needed
+if the changerfile in question uses them.
+
+
+================================
+chg-iomega
+================================
+
+This changer script is designed for IOMEGA or JAZZ disks of various sizes
+as well as any other removable disk media.
+
+This is a PURELY MANUAL changer. It requests insertion of disk media via
+messages on /dev/tty. So it cannot be used via crontab.
+
+Make sure you comply with any of the following.
+- Add statements 
+        tpchanger "chg-iomega"
+        tapedev "file:<mount_point_of_removable_disk>"
+        (e.g. tapedev "file:/mnt/iomega" )
+        tapetype IOMEGA      
+
+        
+        define tapetype IOMEGA {
+            comment "IOMega 250 MB floppys"
+            length 250 mbytes
+            filemark 100 kbytes
+            speed 1 mbytes
+        }
+  to your /etc/amanda/<backup_set>/amanda.conf file
+- 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 a call to amlabel.
+- Be aware 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.
+
+
+==============================
+chg-null
+==============================
+
+A trivial changer which loads/unloads on a null: device.  Useful with
+chg-rait to throw away a parity stripe by puttin on a null jukebox, 
+or for testing.
diff --git a/docs/TAPETYPES b/docs/TAPETYPES
new file mode 100644 (file)
index 0000000..444eb3c
--- /dev/null
@@ -0,0 +1,32 @@
+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 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 considerably modify the available tape space.
+
+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 www.amanda.org.
+
+
+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.  Make sure you
+do not use hardware compression, even if you plan to use hardware
+compression in the future.  `tapetype' writes random data to tape, and
+random data will expand instead of compressing, therefore you'll get
+an estimate that's smaller than expected.
+
diff --git a/docs/UPGRADE b/docs/UPGRADE
new file mode 100644 (file)
index 0000000..b0334fa
--- /dev/null
@@ -0,0 +1,60 @@
+
+Amanda Upgrade Issues
+
+-----
+
+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-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 want to do something like the following:
+
+Before the upgrade (using the old version of amadmin):
+
+       # cd /var/amanda/CONFIG
+       # amadmin CONFIG export > zzz
+       # mkdir backup
+       # mv curinfo* backup
+
+and after the upgrade (using the new version of amadmin):
+
+       # cd /var/amanda/CONFIG
+       # amadmin CONFIG import < zzz
+
+and a month (:-) after you are happy with the new version:
+
+       # cd /var/amanda/CONFIG
+       # rm -rf backup
+
+-----
+
+After 2.4.0, the structure of the directory holding the index files
+was changed to have three levels instead of being flat.  This greatly
+reduces the number of files in a given directory, which was a problem
+for some systems.
+
+The new layout is:
+
+       [indexdir]/hostname/filesystem/YYYYMMDD_L.gz
+
+where hostname and filesystem are "sanitized" versions of the names from
+disklist, i.e. '/' characters are converted to '_' and so on.  This new
+naming convention matches the one used for the text formatted database.
+
+A script is available to convert the flat directory structure to the
+new layout:
+
+       ftp://ftp.amanda.org/pub/amanda/maillist-archives/amanda-users/www/Apr-Jun.1998/msg00428.html
+
+-----
diff --git a/docs/VTAPE-API b/docs/VTAPE-API
new file mode 100644 (file)
index 0000000..6443221
--- /dev/null
@@ -0,0 +1,49 @@
+
+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 devices
+    int tape_open(filename, mode)
+       Acts like open(2) on possibly virtual devices
+    int tape_stat(filename, buf) 
+       Acts like stat(2) on possibly virtual devices
+    int tapefd_close(tapefd)
+       Acts like close(2) on possibly virtual devices
+    int tapefd_fsf(tapefd, count)
+       Forward skips the (possibly virtual) device.
+    int tapefd_read(tapefd, buffer, count)
+       Reads a block from the (possibly virtual) device.
+    int tapefd_rewind(tapefd)
+       Reads a block from a (possibly virtual) device.
+    void tapefd_resetofs(tapefd)
+       Uses lseek() tricks to reset the write/read offset counter on
+       a virtual tape device.
+    int tapefd_unload(tapefd)
+       Unloads the media from a (possibly virtual) device.
+    int tapefd_status(tapefd) 
+       prints status of the (possibly virtual) device to standard output.
+    int tapefd_weof(tapefd, count)
+       writes a filemark/moves to the next file on a device for writing.
+    int tapefd_write(tapefd, buffer, count)
+       writes a block of data to a (possibly virtual) device.
+
+For a tape type xxx, the following routines must be provided, and 
+entered into the table "vtable" in tape-src/tapeio.c:
+    int xxx_tape_access(filename, mode) 
+    int xxx_tape_open(filename, mode)
+    int xxx_tape_stat(filename, buf) 
+    int xxx_tapefd_close(xxx_tapefd)
+    int xxx_tapefd_fsf(xxx_tapefd, count)
+    int xxx_tapefd_read(xxx_tapefd, buffer, count)
+    int xxx_tapefd_rewind(xxx_tapefd)
+    void xxx_tapefd_resetofs(xxx_tapefd)
+    int xxx_tapefd_unload(xxx_tapefd)
+    int xxx_tapefd_status(xxx_tapefd) 
+    int xxx_tapefd_weof(xxx_tapefd, count)
+    int xxx_tapefd_write(xxx_tapefd, buffer, count)
+
+Along with a prefix string which will identify the type.  The initial
+vtape layer has two types "plain" and "rait" (Redundant Array of
+Inexpensive Tapes) but we hope to add a "rmt" (remote tape client),
+and possibly "dvd" types soon.
diff --git a/docs/WHATS.NEW b/docs/WHATS.NEW
new file mode 100644 (file)
index 0000000..c0ff598
--- /dev/null
@@ -0,0 +1,392 @@
+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.
+
+* SAMBA SUPPORT
+
+Read more about this in the file named SAMBA.
+
+* GNUTAR SUPPORT
+
+Amanda now supports dumps made via Gnu TAR.  To use this, set your
+dumptypes set the program name to "GNUTAR":
+
+        dumptype tar-client {
+                ....
+               program "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/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 heirarchy and reads files as a
+regular 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.
+
+
+* MULTIPLE BACKUPS IN PARALLEL FROM ONE CLIENT HOST
+
+A new "maxdumps" parameter for the conf file gives the default value for
+the amount of parallelism per client:
+
+    maxdumps 2 # default max num. dumps to do in parallel per client
+
+If this default parameter is not specified, the default for the default :-0
+is 1.  Then, you can override the parameter per client through the
+dumptype, eg:
+
+        dumptype fast-client {
+                ....
+                maxdumps 4
+        }
+
+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-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:
+
+        wiggum /        fast-comp-user  0
+        wiggum /usr     fast-comp-user  0
+        wiggum /larry   fast-comp-user  1
+        wiggum /curly   fast-comp-user  1
+        wiggum /moe     fast-comp-user  1
+        wiggum /itchy   fast-comp-user  2
+        wiggum /scratchy fast-comp-user 3
+
+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 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 spindle that doesn't interfere with itself.  That is if you don't specify
+any spindle numbers, any and all filesystems on the host can be scheduled
+concurrently up to the maxdumps.
+
+Just to be clear, there's no relation between spindle numbers and maxdumps:
+number the spindles by the disks that you have, even if that's more than
+maxdumps.
+
+Also, I'm not sure that putting spindle numbers everywhere is of much
+value: their purpose is to prevent multiple big dumps from being run at the
+same time on two partitions on the same disk, on the theory that the extra
+seeking between the partitions would cause the dumps to run slower than
+they would if they ran sequentially.  But, given the client-side
+compression and network output that must occur between blocks read from the
+disk, there may be enough slack time at the disk to support the seeks and
+have a little parallelism left over to do some good.
+
+
+* MULTIPLE TAPES IN ONE RUN
+
+I've rewritten the taper - it now supports one run spanning multiple tapes
+if you have a tape-changer.  The necessary changes in support of this have
+also been made to driver and reporter - planner already had support.  There
+are a couple other places that should probably be updated, like amcheck.
+Dumps are not split across tapes - when taper runs into the end of a tape,
+it loads the next tape and tells driver to try sending the dump again.
+
+If you are feeling brave, set "runtapes" to something other than 1.
+
+The new taper also keeps the tape open the entire time it is writing the
+files out - no more having amchecks or other accesses/rewinds in the middle
+of the run screw you royally if they hit when the tape is closed for
+writing a 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 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 conclusions, I'll output it to the log file
+and have the reporter generate a nice table.  The current choices are:
+        not-idle - if there were dumps to do, they got done
+        no-dumpers - there were dumps to do but no dumpers free
+        no-hold - there were dumps to do and dumpers free but the dumps
+                  couldn't go to the holding disks (no-hold conf flag)
+        no-diskspace - no diskspace on holding disks
+        no-bandwidth - ran out of bandwidth
+        client-constrained - couldn't start any dumps because the clients
+                were busy
+
+
+* 2 GB LIMIT REMOVED
+
+I've fixed the 2-gig limits by representing sizes in Kbytes instead of
+bytes everywhere.  This gives us a new 2 TB dump-file size limit (on 32bit
+machines), which should last us a couple more years.  This seemed
+preferable to me than 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, compressing the database after deleting lots of hosts, or editing one
+or all entries in batch form or via a script.
+
+
+---------------------------------------------------------------------------
+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 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
+
+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
+ 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 "amdump-2.2.1".  I recommend that you leave this defined, since
+the this allows 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 file docs/KERBEROS for how to configure the kerberos
+version.  With KRB4_SECURITY defined, there are two new dumptype options:
+
+       krb4-auth       use krb4 auth for this host 
+                       (you can mingle krb hosts & bsd .rhosts in one conf)
+       kencrypt        encrypt this filesystem over the net using the krb4
+                       session key.  About 2x slower.  Good for those root
+                       partitions containing your keyfiles.  Don't want to
+                       give away the keys to an ethernet sniffer!
+
+
+* MULTIPLE HOLDING DISKS
+
+You can have more than one holding disk for those really big installations.
+Just add extra diskdir and disksize lines to your amanda.conf:
+
+       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!
+       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 and used disk space while running.
+
+* REMOTE SELF-CHECKS
+
+Amcheck will now cause self-checks to run on the client hosts, quickly
+detecting which hosts are up and communicating, which have permissions
+problems, etc.  This is amazingly fast for what it does: here it checks
+more than 130 hosts in less than a minute.  My favorite gee-whiz new
+feature!  The new -s and -c options control whether server-only or
+client-only checks are done.
+
+* MMAP SUPPORT
+
+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.
+
+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 because the sysv stuff is better).
+
+
+* GZIP SUPPORT
+
+This was most requested feature #1; I've finally slipped it in.  Define
+HAVE_GZIP in options.h.  See options.h-vanilla for details.  There are two
+new amanda.conf dumptype options "compress-fast" and "compress-best".  The
+default is "compress-fast".  With gzip, compress-fast seems to always do
+better than the old lzw compress (in particular it will never expand the
+file), and runs faster too.  Gzip's compress-best does very good
+compression, but is about twice as slow as the old lzw compress, so you
+don't want to use it for filesystems that take a long time to full-dump
+anyway.
+
+
+* MOUNT POINT NAMES IN DISKLIST
+
+Most requested feature #2: You can specify mount names in the disklist
+instead of dev names.  The rule is, if the filesystem name starts with a
+slash, it is a mount point name, if it doesn't, it is a dev name, and has
+DEVDIR prepended.  For example:
+
+       obelix  sd0a            # dev-name: /dev/sd0a
+       obelix  /obelix         # mount name: /obelix, aka /dev/sd0g
+
+
+* INITIAL TAPE CHANGER SUPPORT INCLUDED
+
+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 docs/TAPE.CHANGERS.  Read that doc for more information.
+
+* GENERIC TAPE CHANGER WRAPPER SCRIPT
+
+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 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 work as-is with tape-changer drivers that use separate
+device names to specify the slot to be loaded, wheres simply opening
+the slot device causes the tape from that slot to be loaded.
+
+chg-generic has its own small conf file.  See example/chg-generic.conf
+for a documented sample.
+
+* NEW "amtape" COMMAND
+
+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 picked by taper for the next amdump
+run.
+
+No man page yet, but running amtape with no arguments gives a detailed
+usage statement.  See docs/TAPE.CHANGERS for more info.
+
+* CHANGER SUPPORT ADDED TO "amlabel" COMMAND
+
+The amlabel command now takes an optional slot argument for labeling
+particular tapes in the tape rack.  See docs/TAPE.CHANGERS for more
+info.
+
+
+* TAPE CHANGER SUPPORT IMPROVED
+
+The specs in docs/TAPE.CHANGERS has 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 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 "needeject" parameters for the chg-generic.conf file.  It now keeps
+track of whether the current slot is loaded into the drive, so that it can
+issue an explicit eject command for those tape changers that need one.  See
+example/chg-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 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 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 can put
+       amdump <conf>; amdump <conf>; amdump <conf>
+in you crontab.  On the down side, this will generate three reports
+instead of one, will do more incremental dumps than necessary, and will
+run slower.  Not very satisfying, but if you *need* to fill more than
+one tape per day NOW, it should work.
+
+
+* BIG PLANNER CHANGES
+
+The support for writing to multiple tapes in one run is almost finished
+now.  See docs/MULTITAPE 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.  Also, the old "mincycle" and "maxcycle" amanda.conf variables are
+deprecated, but still work for now.  "maxcycle" was never used, and
+"mincycle" is now called "dumpcycle".
+
+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 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 specified as "dumpcycle 14" or
+"dumpcycle 2 weeks".  The "2 weeks" specifier works with both the old and
+new versions of planner, because previously "weeks" multiplied by 5, and
+now it multiplies by 7.
+
+Second, planner now warns about impending overwrites of full backups.  If a
+filesystem's last full backup is on a tape that is due to be overwritten in
+the next 5 runs, planner will give you a heads-up about it, so that you can
+restore the filesystem somewhere, or switch that tape out of rotation
+(substitute a new tape with the same label).  This situation often occurs
+after a hardware failure 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 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 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 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 will be reserved for degraded
+mode dumps (e.g. the percentage keeps sliding).
+
diff --git a/docs/WISHLIST b/docs/WISHLIST
new file mode 100644 (file)
index 0000000..6907195
--- /dev/null
@@ -0,0 +1,163 @@
+Amanda WISHLIST
+---------------
+
+These are items that we are planning to address, OR which we would
+like to see happen sometime in the future.  They appear in vaguely
+decreasing order of priority and feasibility.  Of course, we aren't
+promising to deliver anything, but it's a reasonable bet that at least
+the first few things will get done.
+
+You may find more up-to-date information in the Amanda Ongoing
+Projects page, http://www.amanda.org/ongoing.html.
+
+If you have any ideas about any of the following, please send an
+e-mail note to amanda-users@amanda.org or amanda-hackers@amanda.org.
+
+* Setting tapecycle to infinity (which is reasonable for archive
+configurations) will cause planner to crash, because it will try to
+allocate a huge memory block.  The current workaround is to use a
+finite tapecycle; a correct fix would involve dynamically growing the
+structure allocated by planner as needed.
+
+* amcheck and amadmin should check whether the user that invoked it is
+the user configured to run amanda.
+
+* Amanda should be able to retry failed backups in a single run.  So,
+if backup fails because of active 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.
+
+* SAMBA should be treated as a different backup program, not as
+GNUTAR, because it cannot handle dump-style incrementals (as of
+samba-1.9.17p5).  We should be able to back up subdirectories of
+shares (using the -D switch).  It should be possible to specify the
+samba user, instead of assuming user `backup'.  /etc/amandapass could
+be specified (in a backward-compatible way) as follows:
+
+// password [-U default_user] [[-W] default_workgroup]
+//hostname password [-U default_user] [[-W] default_workgroup]
+//hostname/sharename[/subdir] password [-U default_user] [[-W] default_workgroup | -W-]
+
+So that:
+
+// XXXX -W Win32-LAB
+//win-srv XXXX -U srv-backup
+//win-srv/F$ XXXX -U backup
+//other XXXX -U amanda -W-
+
+would be equivalent to:
+
+//win-client1/C$ XXXX -W Win32-LAB
+//win-client2/C$ XXXX -W Win32-LAB
+//win-srv/C$ XXXX -U srv-backup -W Win32-LAB
+//win-srv/D$ XXXX -U srv-backup -W Win32-LAB
+//win-srv/F$ XXXX -U backup -W Win32-LAB
+//other/C$ XXXX -U amanda  (no domain specified)
+
+* When a disk is configured to skip-incr, it will present no estimate
+errors every day except the day it is scheduled for a full dump.
+Besides, it will never be promoted, because no estimate is requested
+on such days.  Maybe we should request a full estimate anyway, and
+skip incrementals after analysis takes place.
+
+* It should be possible to re-generate databases and indexes from
+tapes.
+
+* 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.
+
+* amidxtaped should be able to deal with tape changers, and it should
+check whether it has the appropriate tape before reading any backup
+files from it.  It should also be possible to configure whether
+amidxtaped should decompress the dump stream or not (so amrecover
+could decompress it locally).  Suggested by Chris Jones
+<cjones@honors.montana.edu>
+
+* 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 volunteered to implement the client side.  Sorry, I'm not a
+Mac programmer!
+
+* 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 permissions are set up right, etc.
+  You should be able to force full dumps for nights other than
+tonight.  Rather than one command at a time on the command line,
+amadmin could be a little 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 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, counting the number of times tapes were used, and
+recommending retirement for tapes at the appropriate time?  I'm not
+convinced, but I'm interested in the subject.  What do you think?  How
+does your site deal with this?
+
+* Automatically notice that disks have moved around.  This is a
+nice-to-have but don't hold your breath.  It would be nice if planner
+(via sendsize) would notice and optionally add/delete filesystems as
+they appear/disappear from the fstab.
+
+* Automatically notice that external dumps have been done.  Sendsize
+could also notice if a filesystem was dumped externally to 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.  I think Sun's Backup-Copilot handles this
+well.  We should too.
+
+* Support for client-initiated backups might be interesting, but the
+server would have to keep listening for clients backup requests for a
+configurable 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 as to filesystems, should be supported.  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 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.
+
+* We need a better protocol between the driver and dumpers.
+- setup terminated (to not start to dump onn the same host at the
+  same time).
+- dumper should ask for holding space if the dump is larger that
+  estimated.  It is needed if we want to write a dump on multiple
+  holding disks.
+- driver should ask periodicaly if the dumper is still alive (in case       
+  the dumper hang).
+
+* From: "John R. Jackson" <jrj@gandalf.cc.purdue.edu>
+Here's an idea for someone to think about.  What if we made the
+"length" in a tapetype definition always be the "no compression"
+value?  Then change the dumptype "compress" option to accept
+"hardware" as another type (ala "client" and "server") and let planner
+do its normal thing with that information (including "comprate", which
+at the current default of 50% is the usual first guess for hardware
+compression).
+  This would make setting the tape length value less confusing, and
+make the tapetype program easier to run.  You could even get more
+accurate planning than what is currently available by setting the
+comprate to what you know the data is like on a dumptype by dumptype
+basis.
+
+* We could have an autoflush flag to tell amdump to automatically
+flush the contents of the holding disk to tape.  We'd have to figure
+out a way to tell planner to take that space into account.
+
+* Insert your favorite feature here, and send us e-mail telling about
+what you'd like to see!  Of course, we can't please everyone, and
+can't implement everything, but we are very interested in how other
+sites operate so that we can find common ground and learn from each
+other.  Thanks!
diff --git a/docs/YEAR2000 b/docs/YEAR2000
new file mode 100644 (file)
index 0000000..a826c7b
--- /dev/null
@@ -0,0 +1,5 @@
+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 where years are represented with the
+century-included notation.
diff --git a/docs/ZFTAPE b/docs/ZFTAPE
new file mode 100644 (file)
index 0000000..9541aee
--- /dev/null
@@ -0,0 +1,82 @@
+Amanda with floppy tape drives on Linux: 
+(A.Gebhardt <albrecht.gebhardt@uni-klu.ac.at>)
+
+
+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 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 functions and subroutines from the vtblc utility, distributed with ftape.
+(May be, this library will be part of a future ftape package).
+
+You have to set the raw tape device for volume table operations, usually
+/dev/rawft0, either via "configure --with-ftape-rawdevice=..." or
+with "rawtapedev=..." in amanda.conf (configure checks for /dev/rawft[0-3],
+to get a guess for this value). 
+Dont forget to make this device read/writeable for your backup user.
+
+For compilation you need the header files from ftape 3.04d in your include
+tree.
+
+The volumetable of a tape "amlabeled" TEST-VOL2 with 4 backups on it
+would look like (listed with vtblc utility from ftape):
+
+gamma@backup[backup]$ vtblc
+ Nr  Id          Label                   Date           Start      End    Space
+--------------------------------------------------------------------------------
+  0 VTBL "TEST-VOL2             "  23:08:06 03/15/98        3        4    0.00%
+  1 VTBL "gamma //beta/C 0      "  00:00:00 03/15/98        5      374    0.68%
+  2 VTBL "gamma sda2 0          "  00:00:00 03/15/98      375     1029    1.21%
+  3 VTBL "alpha sda2 0          "  00:00:00 03/15/98     1030     1906    1.62%
+  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%
+
+With lvtblc, currently available with the libvtblc library, you can list 
+the complete label strings 
+(44 characters, not only the first 22 characters as with vtblc):
+  
+gamma@backup[backup]$ lvtblc -l
+ Nr  Id          Label                                         Date 
+--------------------------------------------------------------------------------
+  0 VTBL "TEST-VOL2                                   "  23:08:06 03/15/98
+  1 VTBL "gamma //beta/C 0                            "  00:00:00 03/15/98
+  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
+
+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
+
+kernel 2.0.33, 
+ftape 3.04d, 
+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:
+
+define tapetype DITTO-TR3 {
+    comment "Iomega DITTO 3200 Travan 3 tape drives"
+    length 1500 mbytes          #
+    filemark 29 kbytes          # ???
+    speed 256 kbytes            # = 2000 Kbit/s ?
+}
+
+Note on filemark size:
+Filemarks are not written to the tape (they are written to the header segment 
+and use there 128 byte), so their size could even be 0. But a tape segment 
+takes at least 29 kb (+3 kb ecc-code = 32 kb), so in the worst case an eof will
+waste 29 kb.
+
diff --git a/docs/chg-scsi.notes b/docs/chg-scsi.notes
new file mode 100644 (file)
index 0000000..220e66c
--- /dev/null
@@ -0,0 +1,343 @@
+CHG-SCSI
+
+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 docs/TAPE.CHANGERS for additional details.
+
+My equipment list is as follows:
+       Redhat 7.0 machine 
+               - dual processor p-III
+               - sony dds3 tape drive
+               - lots of hard disk space
+               - Quantum/ATL L500 scsi changer
+                       1 DLT tape drive (three possible)
+                       barcode reader
+                       fourteen tape slots 
+
+I base this documentation on the following:
+       mtx version 1.2.16rel 
+       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
+       the SCSI bus and IDE interface 2nd ed by Friedhelm Schmidt
+               pub: Addision Wesley 1998
+
+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.
+
+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 .
+
+------------------------
+command line options:
+
+chg-scsi's command line options:
+       -slot <param>
+       -info
+       -reset
+       -eject
+       -clean
+       -label <param>
+       -search <param>
+       -status <param>
+       -trace <param>
+       -inventory
+       -dumpdb
+       -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.
+
+-slot <param> command:
+
+       this command takes either a slot number, or any one of the
+       following: 
+               current, next, prev, first, last, advance
+
+       It then loads the appropriate tape into the drive.
+
+       Note that if the tape is already loaded, no changer motion will
+       happen.  No reading of the tape is done here.
+
+-info command:
+       
+       four numbers are printed:
+       <slot# loaded> <number of slots> <reversable> <searchable>
+
+       with chg-scsi, the reversable number is always 1.  Searchable is
+       set based on if a barcode reader is available and working
+       correctly.
+
+-reset command:
+       
+       Tape is unloaded, and slot 0 is loaded.  No actual reset command
+       is sent to the changer.
+
+-eject command:
+       
+       Tape is unloaded, and put back into its original slot.
+
+-clean command:
+       
+       Cleaning tape (if configured) is loaded into the tape.  It is
+       probably unloaded when done.  I haven't looked closely at this
+       yet.
+
+-label <param> command:  
+
+       This appears to take the currently loaded tape's barcode and
+       write it to the 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 labelfile.  If a barcode is found, then that
+       tape is loaded directly.
+
+       I believe the fallback is to search the entire magazine.
+
+-status command:
+       
+       the tape changer is queried, and the results are printed out.
+       Values printed are what slots exist, are they full or empty, and
+       what volume labels (barcodes) they are.
+               Q. what about changers that don't retain current slot?
+               A. this is what the "statfile" is for.
+       
+-trace command:
+       
+       present only for a particular type of changer.
+       
+-inventory:  (this takes a LONG time to do)
+       
+       1) unloads tape back to its slot
+       2) issues command to changer to do an inventory of itself (read all
+               barcodes...)
+       3) loads each tape, retrieves the barcode, and reads the amanda
+               label off of the tape itself
+       4) stores/updates the label database file
+       
+-dumpdb:
+       
+       prints out in human readable form the label database contents
+       from the labelfile.
+
+-scan:  (aka scanbus)
+       scans the scsi generic interfaces (eg: linux sg), and prints out the
+       device 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 configuration
+       notes below.
+
+-genconf:
+
+       prints out a SAMPLE changer.conf file.  Note that I said sample.
+       except for that it also does a scanbus.  if you have more than
+       one tape drive, please be certain it is correct as chg-scsi uses
+       the first one it finds.
+       
+       Please refer to my configuration notes below.
+
+--------------------------------------------
+
+changer.conf notes:
+
+Here, I try to be a bit more clear on what these config values mean.  
+
+"number_configs" MUST be the first entry (not counting comments)
+
+"emubarcode" will set this value in chg-scsi regardless of the value you
+try to assign it.  If you don't want "emubarcode" set, don't list it!
+
+"havebarcode"  
+       have barcode is tempered by what devices chg-scsi is aware of.
+       if chg-scsi doesn't know about your changer explicitly, it will
+       default to a default changer.  the default changer has no
+       barcode reader.
+       
+       In a patch I plan to post, I have added a generic changer that
+       does use a barcode.  set "changerident" to "genericbarcode" to
+       use this.
+       
+"sleep"
+       number of seconds for chg-scsi to wait for a "tape drive ready"
+       command after loading a new tape.  Mine is 140 as I have a DLT
+       tape drive, and my tape drive manual reports a max of 133
+       seconds to be ready.
+
+"config" 
+       this is a header telling chg-scsi that all values following, up
+       to the next "config" line apply to this drive number.  It is
+       this number that is refered to in your amanda.conf file as line
+       "tapedev"
+       
+"drivenum"
+       this is the tape drive number in your changer.  for a single
+       tape drive, this is zero.  Mine can handle up to three, so I
+       expect I could make this 0, 1, or 2.
+
+"dev"
+       the scsi device of your tape drive.  under linux, in my case
+       it is /dev/nst1.  This MUST be defined.
+
+"scsitapedev"
+       the generic scsi device of your tape drive.  this is simply the
+       generic interface to the device "dev" above.  This entry is
+       optional.  In my case, it is /dev/sg2.  If this entry exists and
+       is legitimate, then scsi commands are formed directly instead of
+       using ioctl commands.
+
+"startuse"
+"enduse"
+       the start and end slots of your changer.  Note that these also
+       start with zero.
+
+"eject"
+       chg-scsi tells the tape changer to eject.  You might need to
+       explicitly tell the tape drive to unload first.  that's what
+       this setting is for.  Have you ever removed a loaded VCR tape
+       by hand?
+
+"changerident" 
+       chg-scsi will first read the changer's identification from the
+       return of the scsi "inquiry" command.  If changerident is set in
+       the configuration file, the scsi inquiry's value is overridden.
+       chg-scsi will attempt to match the value with its built-in
+       changertypes.
+
+       "generic" is what the chg-scsi will default to
+       "genericbarcode" is a hack of mine that forces the changer's
+               barcode reader to work.  Note that if your changer
+               uses a superset of the scsi command set, this probably
+               won't work.
+       "L500" is another addition of mine that will enable a
+               quantum/atl L500 to work correctly.  It might even work
+               with an L200.
+
+       other values are (taken from the code)
+               C1553A (HP Auto Loader)
+               EXB-10e, EXB-120 (Exabyte Robot)
+               EXB-85058HE-0000 (Exabyte Tape)
+               TDS 1420 (Tandberg Robot)
+               VLS DLT, VLS SDX (ADIC VLS DLT Library)
+               FastStor DLT (ADIC FastStor DLT Library) 
+               Scalar DLT 448 (ADIC DLT 448)
+               215 (Spectra Logic TreeFrog)
+               Quad 7 (Breece Hill)
+               DLT7000, DLT4000 (DLT Tape)
+
+"debuglevel"
+       setting this to "9:0" is very informative.
+
+"statfile" 
+       stores which "slot" that the tape in the drive came from
+
+"labelfile"
+       binary file that stores the tape header and barcode information
+
+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
+
+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) is working on this.
+
+-----------------------------------------------
+
+Configuration notes:
+
+       (assuming one changer with one tape drive!)
+
+in "amanda.conf":
+
+       set tpchanger to chg-scsi
+       set changerfile to <pathname>/changer.conf
+       set tapedev to 0
+       set changerdev to /dev/<changer generic device>
+               - this value is usually listed in the system boot
+                 messages or will be printed via syslog when the
+                 appropriate kernel module is loaded. 
+                       eg: linux "modprobe sg"
+
+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/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 that "sg0" was not the
+       correct tape!
+
+       set scsitapedev to "/dev/<generic device>"
+
+       if you have no barcode, try "changerident generic"
+       if you have a barcode reader try "changerident genericbarcode"
+
+
+
+-----------------------------------------------
+
+Hacking notes:
+       
+my hacks are:
+       adding printout of "emubarcode" values in the debug file
+       
+       added dlt8000 tape drive to ChangerIO[], and SenseType[]
+       added genericbarcode to ChangerIO[], and SenseType[]
+       added L500 to ChangerIO[], and SenseType[]
+       
+
+       added a couple of basic sensecodes listed in the scsi specs for
+       the generic and genericbarcode tape changers.
+
+
+
+My desires are:
+       modify the sensecode code such that all scsi devices inherit the
+       standard scsi codes and may override or append to them as
+       needed.
+
+       modify the configuration reading code and the "inquiry" command
+       to allow spaces.  
+               eg: my changer displays the following ident data: 
+               "L500   6320000" but I had to create a type called "L500"
+               or else the spaces would throw off the comparisons.
+
diff --git a/example/3hole.ps b/example/3hole.ps
new file mode 100644 (file)
index 0000000..1f37605
--- /dev/null
@@ -0,0 +1,994 @@
+%!
+%%BoundingBox: 25 25 290 900
+%%Title: AMANDA Full Page Label
+%%Creator: Amanda reporter
+%%Pages: 1
+%%EndComments
+
+%%%%
+%% This template file is used by AMANDA to create PostScript dump log
+%% listings for each run suitable for three-hole punching.
+%%
+%% This prologue is based on one from Steven Freed <sfreed@gilasoft.com>
+%% called 8.5x11.ps and was enhanced with assistance from Dale Talcott
+%% <aeh@purdue.edu>.
+%%
+%% John R. Jackson, Technical Software Specialist, jrj@purdue.edu
+%%%%
+
+%%%
+% If you are printing duplex, change the 0 to a 1 in the following line:
+%%%
+
+/DoDuplex 0 def
+
+%%%
+% The following string (inside the parenthesis) will be displayed as
+% the "Location" (e.g. organization) on each page (see the page format
+% below).
+%%%
+
+/LocationString                (Magic Software Development, Inc.) def
+
+%%%
+% Set the margin widths.  This may need adjustment based on how your
+% printer defines the printable area on a page.
+%%%
+
+/inch {
+       72 mul                                  % one inch == 72 points
+} def
+/mm {
+       25.4 div                                % one inch == 25.4 mm
+       inch                                    % convert inches to points
+} def
+
+/TopMargin             0.25 inch def
+/BottomMargin          0.25 inch def
+
+/OddLeftMargin         0.625 inch def          % 5/8 inch
+/OddRightMargin                0.25 inch def
+
+DoDuplex 0 eq {
+       % even and odd are the same if duplex is not used
+       /EvenLeftMargin OddLeftMargin def
+       /EvenRightMargin OddRightMargin def
+} {
+       % otherwise they are reversed
+       /EvenLeftMargin OddRightMargin def
+       /EvenRightMargin OddLeftMargin def
+} ifelse
+
+%%%
+% A page is made up of these parts.  The base name of the internal variable
+% related to each is shown in parenthesis:
+%
+%      tape name                               (Title)
+%      page number                             (Page)
+%      version of Amanda                       (Vers)
+%      location (e.g. organisation)            (Loc)
+%      date                                    (Date)
+%      statistics (about the Amanda run)       (Stat)
+%      message (how to do a restore)           (Mess)
+%      header for the filesystem list          (Heading)
+%      filesystem list                         (Host)
+%
+% Geometrically, an odd numbered page looks like this:
+%
+%   +----+-------------------+
+%   |        TAPE_NAME  page |   <- section 'A'
+%   | version  location date |   <- section 'B'
+%   +------------------------+
+%   |statistics  |  message  |   <- section 'C' | 'F'
+%   +----+--+--------+-------+
+%   | f# hst fs lvl O-KB C-KB|   <- section 'D'
+%   +-------+--------+-------+
+%   |       |        |       |   <- section 'E'
+%   |       |        |       |
+%   v       v        v       v
+%
+% Even numbered pages look the same unless DoDuplex is turned on, in
+% which case the "page" field is on the left and the gutter width for
+% the punch is on the right (instead of the left).
+%%%
+
+%%%
+% section 'A' fonts and strings
+%%%
+
+/TitleFontSize         24 def                  % 24 point Helvetica-Bold
+/TitleFont
+       /Helvetica-Bold findfont
+       TitleFontSize scalefont
+def
+
+/PageFontSize          11 def                  % 11 point Palatino-Bold
+/PageFont
+       /Palatino-Bold findfont
+       PageFontSize scalefont
+def
+/PageString1           (Page ) def
+/PageString2           ( of ) def
+
+%%%
+% section 'B' fonts and strings
+%%%
+
+/VersFontSize          11 def                  % 11 point Palatino-Bold
+/VersFont
+       /Palatino-Bold findfont
+       VersFontSize scalefont
+def
+
+/LocFontSize           12 def                  % 12 point Helvetica-Bold
+/LocFont
+       /Helvetica-Bold findfont
+       LocFontSize scalefont
+def
+
+/DateFontSize          11 def                  % 11 point Palatino-Bold
+/DateFont
+       /Palatino-Bold findfont
+       DateFontSize scalefont
+def
+
+%%%
+% section 'C' font
+%%%
+
+/StatFontSize          9 def                   % 9 point Courier
+/StatFont
+       /Courier findfont
+       StatFontSize scalefont
+def
+
+%%%
+% section 'D' font and strings
+%%%
+
+/HeadingFontSize       9 def                   % 9 point Palatino-Bold
+/HeadingFont
+       /Palatino-Bold findfont
+       HeadingFontSize scalefont
+def
+
+/HeadingFileString     (File #) def
+/HeadingHostString     (Host) def
+/HeadingFsString       (File System) def
+/HeadingLvlString      (Level) def
+/HeadingOSizeString1   (Original) def
+/HeadingOSizeString2   (File Size (KB)) def
+/HeadingCSizeString1   (Compressed) def
+/HeadingCSizeString2   (File Size (KB)) def
+
+%%%
+% section 'E' font
+%%%
+
+/HostFontSize          9 def                   % 9 point Courier
+/HostFont
+       /Courier findfont
+       HostFontSize scalefont
+def
+
+%%%
+% section 'F' font and strings
+%%%
+
+/MessFontSize          9 def                   % 9 point Courier
+/MessFont
+       /Courier findfont
+       MessFontSize scalefont
+def
+
+/MessString1 (To restore:) def
+/MessString2 (   position tape at the start of the file and run:) def
+/MessString3 (      dd if=$TAPE bs=32k skip=1 | zcat | restore -ibf 2 -) def
+/MessString4 (   or run:) def
+/MessString5 (      amrestore -p $TAPE <host> <filesystem> | restore -ibf 2 -) def
+
+%%%%
+%% END OF USER-CONFIGURABLE OPTIONS
+%%
+%% The rest of this file contains the internal functions used to draw
+%% the page and (hopefully) do not need any changes.
+%%%%
+
+/setTitleFont {
+       TitleFont setfont                       % make TitleFont current
+} def
+/setPageFont {
+       PageFont setfont                        % make PageFont current
+} def
+/setVersFont {
+       VersFont setfont                        % make VersFont current
+} def
+/setLocFont {
+       LocFont setfont                         % make LocFont current
+} def
+/setDateFont {
+       DateFont setfont                        % make DateFont current
+} def
+/setStatFont {
+       StatFont setfont                        % make StatFont current
+} def
+/setHeadingFont {
+       HeadingFont setfont                     % make HeadingFont current
+} def
+/setHostFont {
+       HostFont setfont                        % make HostFont current
+} def
+/setMessFont {
+       MessFont setfont                        % make MessFont current
+} def
+
+%%%
+% apush -- increase an array size by one and push a value on the end
+% usage:       value array apush array
+% example:     /jj 0 array def
+%              /jj (first) jj apush def
+%              /jj (second) jj apush def
+%              /jj (third) jj apush def
+%%%
+
+/apush {
+       exch                                    % [ array value ]
+       /.apush exch def                        % save and pop the value
+                                               % [ array ]
+       aload                                   % [ old ... array ]
+       length                                  % length of the old array
+                                               % [ old ... length ]
+       1 add                                   % bump it by one
+                                               % [ old ... length+1 ]
+       array                                   % create the new array
+                                               % [ old ... newarray ]
+       .apush exch                             % [ old ... value newarray ]
+       astore                                  % store the values
+                                               % [ newarray ]
+} def
+
+%%%
+% box -- draw a box
+% usage:       llx lly urx ury box -
+%%%
+
+/box {
+       3 index 2 1 add index moveto
+       3 index 0 1 add index lineto
+       1 index 0 1 add index lineto
+       1 index 2 1 add index lineto
+       pop pop pop pop
+       closepath
+} def
+
+%%%
+% concat -- join two strings
+% usage:       str1 str2 concat new
+%%%
+
+/concat {
+       exch                                    % str2 str1
+       dup                                     % str2 str1
+       length                                  % str2 str1 str1l
+       2 index                                 % str2 str1 str1l str2
+       length add string                       % str2 str1 new
+       dup dup                                 % str2 str1 new new new
+       4 2 roll                                % str2 new new str1 new
+       copy                                    % str2 new new (str1)
+       length                                  % str2 new new newl
+       4 -1 roll                               % new new newl str2
+       putinterval                             % new
+} bind def
+
+%%%
+% max -- return the max of two numbers
+% usage:       a b max a_or_b
+%%%
+
+/max {
+       1 index 1 index                         % [ a b a b ]
+       lt {
+               exch                            % [ b a ]
+       } if
+       pop
+} def
+
+%%%
+% Set the basic drawable area width and height.
+%%%
+
+clippath                                       % make the clip area the path
+pathbbox                                       % and get its bounding box
+                                               % [ llx lly urx ury ]
+exch                                           % [ llx lly ury urx ]
+4 1 roll                                       % [ urx llx lly ury ]
+exch sub                                       % total height
+TopMargin sub BottomMargin sub                 % minus the margins
+/PageHeight exch def                           % [ urx llx ]
+sub                                            % total width
+EvenLeftMargin sub EvenRightMargin sub         % minus the margins
+/PageWidth exch def
+newpath                                                % zap the path
+
+%%%
+% Define rectangles to separate the regions.
+%%%
+
+/TitleBox {
+       0                                       % [ llx ]
+       PageHeight                              % [ llx PageHeight ]
+         TitleFontSize PageFontSize max        % 'A' height
+         2 add                                 % space between 'A' and 'B'
+         4 add                                 % space below 'B'
+         VersFontSize LocFontSize max
+                      DateFontSize max         % 'B' height
+         add                                   % 'A' height+space+'B' height
+         sub                                   % [ llx lly ]
+       PageWidth                               % [ llx lly urx ]
+       PageHeight                              % [ llx lly urx ury ]
+} bind def
+
+/StatBox {
+       TitleBox                                % [ llx lly urx ury ]
+       pop                                     % [ llx lly urx ]
+       3 1 roll dup                            % [ urx llx lly lly ]
+       StatStrings length                      % number of status lines
+       StatFontSize mul                        % height of status lines
+       MessStrings length                      % number of message lines
+       MessFontSize mul                        % height of message lines
+       max                                     % max height
+       2 add                                   % space above
+       4 add                                   % space below
+       sub                                     % [ urx llx ury lly ]
+       exch                                    % [ urx llx lly ury ]
+       4 -1 roll                               % [ llx lly ury urx ]
+       exch                                    % [ llx lly urx ury ]
+} def
+
+/CFLine {
+       StatBox                                 % [ llx lly urx ury ]
+       3 1 roll                                % [ llx ury lly urx ]
+       pop exch                                % [ llx lly ury ]
+       3 -1 roll                               % [ lly ury llx ]
+       setStatFont
+       0
+       StatStrings {
+               stringwidth pop max
+       } forall
+       add
+       (nn) stringwidth pop add                % left and right padding
+       dup                                     % [ ly uy x x ]
+       3 1 roll                                % [ ly x uy x ]
+       4 1 roll                                % [ x ly x uy ]
+} def
+
+/HeadingBox {
+       StatBox                                 % [ llx lly urx ury ]
+       pop                                     % [ llx lly urx ]
+       3 1 roll dup                            % [ urx llx lly lly ]
+       HeadingFontSize 2 mul                   % two heading lines
+       2 add                                   % space above
+       4 add                                   % space below
+       sub                                     % [ urx llx ury lly ]
+       exch                                    % [ urx llx lly ury ]
+       4 -1 roll                               % [ llx lly ury urx ]
+       exch                                    % [ llx lly urx ury ]
+} def
+
+/HostBox {
+       HeadingBox                              % [ llx lly urx ury ]
+       pop                                     % [ llx lly urx ]
+       3 1 roll 0                              % [ urx llx lly 0 ]
+       exch                                    % [ urx llx lly ury ]
+       4 -1 roll                               % [ llx lly ury urx ]
+       exch                                    % [ llx lly urx ury ]
+} def
+
+%%%
+% Compute the center point for the section 'A' title text.
+%%%
+
+/TitlePos {
+       TitleBox                                % [ llx lly urx ury ]
+       TitleFontSize sub                       % [ llx lly urx y ]
+       3 -1 roll                               % [ llx urx y lly ]
+       pop                                     % [ llx urx y ]
+       3 1 roll                                % [ y llx urx ]
+       exch dup                                % [ y urx llx llx ]
+       3 -1 roll                               % [ y llx llx urx ]
+       exch sub 2 div add                      % [ y x ]
+       exch                                    % [ x y ]
+} def
+
+%%%
+% Compute the position of the odd page string (right adjusted).
+%%%
+
+/OddPagePos {
+       TitleBox                                % [ llx lly urx ury ]
+       4 -2 roll                               % [ urx ury llx lly ]
+       pop pop                                 % [ x y ]
+       exch                                    % [ y x ]
+       setPageFont
+       (n) stringwidth pop sub                 % a little padding
+       exch                                    % [ x y ]
+       PageFontSize sub
+       2 sub                                   % space above
+} def
+
+%%%
+% Compute the position of the even page string (left adjusted).
+% Not used if DoDuplex is off.
+%%%
+
+/EvenPagePos {
+       TitleBox                                % [ llx lly urx ury ]
+       4 1 roll                                % [ ury llx lly urx ]
+       pop pop                                 % [ y x ]
+       setPageFont
+       (n) stringwidth pop add                 % a little padding
+       exch                                    % [ x y ]
+       PageFontSize sub
+       2 sub                                   % space above
+} def
+
+%%%
+% Compute the position of the version string.
+%%%
+
+/VersPos {
+       TitleBox                                % [ llx lly urx ury ]
+       pop pop                                 % [ llx lly ]
+       exch                                    % [ lly llx ]
+       setVersFont
+       (n) stringwidth pop add                 % a little padding
+       exch                                    % [ x y ]
+       4 add                                   % space below
+} def
+
+%%%
+% Compute the position of the location string (centered).
+%%%
+
+/LocPos {
+       TitleBox                                % [ llx lly urx ury ]
+       pop                                     % [ llx lly urx ]
+       3 -1 roll                               % [ lly urx llx ]
+       dup                                     % [ lly urx llx llx ]
+       3 -1 roll                               % [ lly llx llx urx ]
+       exch sub 2 div add                      % [ y x ]
+       exch                                    % [ x y ]
+       4 add                                   % space below
+} def
+
+%%%
+% Compute the position of the date string (right adjusted).
+%%%
+
+/DatePos {
+       TitleBox                                % [ llx lly urx ury ]
+       pop                                     % [ llx lly urx ]
+       3 -1 roll                               % [ lly urx llx ]
+       pop                                     % [ y x ]
+       setDateFont
+       (n) stringwidth pop sub                 % a little padding
+       exch                                    % [ x y ]
+       4 add                                   % space below
+} def
+
+%%%
+% Compute the position of the top status string.
+%%%
+
+/StatPos {
+       StatBox                                 % [ llx lly urx ury ]
+       exch pop                                % [ llx lly ury ]
+       dup                                     % [ llx lly ury ury ]
+       3 1 roll                                % [ llx ury lly ury ]
+       exch sub                                % [ llx ury box_height ]
+       StatStrings length                      % number of status lines
+       StatFontSize mul                        % height of status lines
+       sub 2 div                               % [ llx ury space_above ]
+       sub
+       StatFontSize sub                        % [ llx y ]
+       2 add                                   % space above
+       exch                                    % [ y llx ]
+       setStatFont
+       (n) stringwidth pop add                 % a little padding
+       exch                                    % [ x y ]
+} def
+
+%%%
+% Compute the position of the top message string.
+%%%
+
+/MessPos {
+       CFLine                                  % [ lx ly ux uy ]
+       exch pop                                % [ lx ly uy ]
+       dup                                     % [ lx ly uy uy ]
+       3 1 roll                                % [ lx uy ly uy ]
+       exch sub                                % [ lx uy box_height ]
+       MessStrings length                      % number of status lines
+       MessFontSize mul                        % height of status lines
+       sub 2 div                               % [ lx uy space_above ]
+       sub
+       MessFontSize sub                        % [ lx y ]
+       2 add                                   % space above
+       exch                                    % [ y lx ]
+       setMessFont
+       (n) stringwidth pop add                 % a little padding
+       exch                                    % [ x y ]
+} def
+
+%%%
+% Compute the heading positions that start at the left.
+%%%
+
+/HeadingFilePos {
+       HeadingBox                              % [ llx lly urx ury ]
+       pop pop                                 % [ llx lly ]
+       exch                                    % [ y x ]
+       setHeadingFont
+       (n) stringwidth pop add                 % a little padding
+       dup
+       HeadingFileString stringwidth pop add
+       /HeadingFilePosX exch def               % for BuildHost
+       exch                                    % [ x y ]
+       4 add                                   % space below
+} def
+
+/HeadingHostPos {
+       HeadingFilePos                          % [ x y ]
+       exch                                    % [ y x ]
+       setHeadingFont
+       (nn) stringwidth pop add                % a little padding
+       HeadingFileString stringwidth pop add
+       dup /HeadingHostPosX exch def           % for BuildHost
+       exch                                    % [ x y ]
+} def
+
+/HeadingFsPos {
+       HeadingHostPos                          % [ x y ]
+       exch                                    % [ y x ]
+       setHostFont                             % use the host font for sizes
+       HostNameWidth add
+       (nn) stringwidth pop add                % a little padding
+       dup /HeadingFsPosX exch def             % for BuildHost
+       exch                                    % [ x y ]
+       setHeadingFont                          % leave it in the heading font
+} def
+
+%%%
+% Compute the heading positions that start at the right (and are right
+% justified).
+%%%
+
+/HeadingCSizePos2 {
+       HeadingBox                              % [ llx lly urx ury ]
+       pop                                     % [ llx lly urx ]
+       3 -1 roll                               % [ lly urx llx ]
+       pop                                     % [ lly urx ]
+       setHeadingFont
+       (n) stringwidth pop sub                 % a little padding
+       dup /HeadingCSizePosX exch def          % for BuildHost
+       exch                                    % [ x y ]
+       4 add                                   % space below
+} def
+
+/HeadingCSizePos1 {
+       HeadingCSizePos2
+       HeadingFontSize add
+} def
+
+/HeadingOSizePos2 {
+       HeadingCSizePos2                        % [ x y ]
+       exch                                    % [ y x ]
+       setHeadingFont
+       HeadingCSizeString1 stringwidth pop
+       HeadingCSizeString2 stringwidth pop
+       max                                     % widest string
+       sub                                     % [ y x ]
+       (n) stringwidth pop sub                 % a little padding
+       dup /HeadingOSizePosX exch def          % for BuildHost
+       exch                                    % [ x y ]
+} def
+
+/HeadingOSizePos1 {
+       HeadingOSizePos2
+       HeadingFontSize add
+} def
+
+/HeadingLvlPos {
+       HeadingOSizePos2                        % [ x y ]
+       exch                                    % [ y x ]
+       setHeadingFont
+       HeadingOSizeString1 stringwidth pop
+       HeadingOSizeString2 stringwidth pop
+       max                                     % widest string
+       sub                                     % [ y x ]
+       HeadingLvlString stringwidth pop
+       2 div sub                               % set up for centering
+       (n) stringwidth pop sub                 % a little padding
+       dup /HeadingLvlPosX exch def            % for BuildHost
+       exch                                    % [ x y ]
+} def
+
+%%%%
+%% The following functions save strings for each kind of information
+%% and handle the calls generated by amreport.
+%%%%
+
+%%%
+% DrawStat saves a string in the next position for section 'A'.
+%%%
+
+/StatStrings 0 array def
+
+/DrawStat {
+       /StatStrings exch                       % [ /StatStrings value ]
+       StatStrings apush def
+} def
+
+%%%
+% DrawMess saves a string in the next position for section 'F'.
+%%%
+
+/MessStrings 0 array def
+
+/DrawMess {
+       /MessStrings exch                       % [ /MessStrings value ]
+       MessStrings apush def
+} def
+
+MessString1 DrawMess
+MessString2 DrawMess
+MessString3 DrawMess
+MessString4 DrawMess
+MessString5 DrawMess
+
+%%%
+% DrawTitle saves the title string.
+%%%
+
+/TitleString () def
+
+/DrawTitle {
+       /TitleString exch def
+} def
+
+%%%
+% DrawDate save the date string.
+%%%
+
+/DateString () def
+
+/DrawDate {
+       /DateString exch def
+} def
+
+%%%
+% DrawLoc saves the location string.  Amreport does not generate this
+% call and the initial value has been set at the start of this file
+% in the user-changeable area.
+%%%
+
+/DrawLoc {
+       /LocationString exch def
+} def
+
+%%%
+% DrawVers saves the Amanda version string.
+%%%
+
+/VersionString () def
+
+/DrawVers {
+       /VersionString exch def
+} def
+
+%%%
+% DrawHost expects six strings on the stack:
+%
+%      Host Name
+%      Partition Name
+%      Dump Level
+%      Tape File Number
+%      Original Size
+%      Compressed Size
+%
+% They are saved for processing by the final showpage.
+%%%
+
+/HostStrings 0 array def
+/HostNameWidth 0 def
+
+/DrawHost {
+       setHostFont
+       5 index                                 % copy of host name
+       stringwidth pop
+       HostNameWidth max
+       /HostNameWidth exch def                 % find maximum host name width
+       6 array astore                          % convert args to an array
+       /HostStrings exch                       % [ /HostStrings value ]
+       HostStrings apush def
+} def
+
+%%%%
+%% Functions used during actual page drawing.
+%%%%
+
+%%%
+% Center a string on the current point.
+%%%
+
+/Center {
+       dup stringwidth pop
+       2 div
+       neg 0 rmoveto
+} bind def
+
+%%%
+% Right justify a string on the current point.
+%%%
+
+/RightJustify {
+       dup                                     % [ (str) (str) ]
+       stringwidth pop                         % [ (str) width ]
+       neg 0 rmoveto
+} bind def
+
+%%%
+% The main page drawing function called when a new page is started.
+%%%
+
+/PageCount 1 def
+
+/BuildPage {
+
+       % translate to leave room for the margins
+
+       PageCount 2 mod 1 eq {
+               OddLeftMargin
+       } {
+               EvenLeftMargin
+       } ifelse
+       BottomMargin translate
+
+       % draw the boxes
+
+       currentgray                             % save the gray value
+       0 setgray                               % turn off gray
+       currentlinewidth                        % save the current line width
+       2 setlinewidth                          % thick lines
+
+       StatBox box stroke
+       TitleBox box stroke
+       HeadingBox box stroke
+       HostBox box stroke
+       CFLine moveto lineto stroke
+
+       setlinewidth                            % restore the line width
+       setgray                                 % restore the gray value
+
+       % draw the title
+
+       setTitleFont
+       TitleString
+       TitlePos moveto
+       Center
+       show
+
+       % draw the page number string
+
+       setPageFont
+       PageCount
+       32 string                               % big enough for the number
+       cvs                                     % convert the number
+       PageString1 exch concat                 % (Page NN)
+       PageString2 concat                      % (Page NN of )
+       PageMaxString concat                    % (Page NN of MM)
+       PageCount 2 mod 1 eq {
+               OddPagePos moveto
+               RightJustify
+       } {
+               DoDuplex 0 eq {
+                       OddPagePos moveto
+                       RightJustify
+               } {
+                       EvenPagePos moveto
+               } ifelse
+       } ifelse
+       show
+       /PageCount PageCount 1 add def          % bump the page counter
+
+       % draw the version string
+
+       setVersFont
+       VersionString
+       VersPos moveto
+       show
+
+       % draw the location
+
+       setLocFont
+        LocationString
+       LocPos moveto
+       Center
+       show
+
+       % draw the date string
+
+       setDateFont
+       DateString
+       DatePos moveto
+       RightJustify
+       show
+
+       % draw the status lines
+
+       setStatFont
+       StatPos
+       /CurrentY exch def
+       StatStrings {
+               exch dup CurrentY moveto
+               exch show
+               /CurrentY CurrentY StatFontSize sub def
+       } forall
+       pop                                     % get rid of the X value
+
+       % draw the messages
+
+        setMessFont
+       MessPos
+       /CurrentY exch def
+       MessStrings {
+               exch dup CurrentY moveto
+               exch show
+               /CurrentY CurrentY MessFontSize sub def
+       } forall
+       pop                                     % get rid of the X value
+
+       % draw the headings
+
+       setHeadingFont
+       HeadingFilePos moveto
+         HeadingFileString
+         show
+       HeadingHostPos moveto
+         HeadingHostString
+         show
+       HeadingFsPos moveto
+         HeadingFsString
+         show
+       HeadingLvlPos moveto
+         HeadingLvlString
+         Center
+         show
+       HeadingOSizePos1 moveto
+         HeadingOSizeString1
+         RightJustify
+         show
+       HeadingOSizePos2 moveto
+         HeadingOSizeString2
+         RightJustify
+         show
+       HeadingCSizePos1 moveto
+         HeadingCSizeString1
+         RightJustify
+         show
+       HeadingCSizePos2 moveto
+         HeadingCSizeString2
+         RightJustify
+         show
+
+       % reset the host position variables
+
+       HeadingBox                              % [ llx lly urx ury ]
+       pop pop exch pop                        % [ lly ]
+       HostFontSize sub
+       /CurrentY exch def
+} def
+
+%%%
+% Build the host line on the page.
+%%%
+
+/BuildHost {
+       setHostFont
+       HeadingCSizePosX CurrentY moveto
+         RightJustify
+         show                                  % compressed size
+       HeadingOSizePosX CurrentY moveto
+         RightJustify
+         show                                  % original size
+       HeadingFilePosX CurrentY moveto
+         RightJustify
+         show                                  % tape file number
+       HeadingLvlPosX CurrentY moveto
+         show                                  % dump level
+       HeadingFsPosX CurrentY moveto
+         show                                  % file system
+       HeadingHostPosX CurrentY moveto
+         show                                  % host
+
+       HostCount 0 gt {                        % if not at end of page
+               currentlinewidth                % save the line width
+               .25 setlinewidth                % thin lines
+
+               CurrentY
+               dup                             % keep this CurrentY
+               HostFontSize 2 add sub
+               /CurrentY exch def              % update CurrentY for next host
+
+               2 sub                           % move down a little
+               dup
+               0 exch                          % [ y 0 y ]
+               moveto
+               PageWidth exch                  % [ PageWidth y ]
+               lineto stroke
+               setlinewidth                    % restore the line width
+       } if
+} def
+
+%%%
+% Magic time -- the input consists of lots of calls to the /DrawXXX
+% functions, which gather the text into memory.  It ends with a showpage,
+% which we hook here to do all the real imaging after everything has
+% been collected.  The only reason to do all this is so we can know
+% how many pages will be generated for the "Page N of M" line.
+%%%
+
+25 dict begin                                  % emperically enough entries
+       /*showpage /showpage load def           % rename showpage to *showpage
+                                               % in our dictionary
+       /showpage {
+               HostBox                         % [ llx lly urx ury ]
+               exch pop                        % [ llx lly ury ]
+               exch sub                        % [ llx height ]
+               exch pop                        % [ height ]
+               cvi                             % idiv requires integers
+               HostFontSize
+               2 add                           % space below each line
+               idiv                            % hosts per page
+               dup
+               /HostMax exch def
+
+               dup
+               /HostCount exch def             % initialize the counter
+
+               dup                             % [ HostMax HostMax ]
+               HostStrings length              % number of hosts
+               add 1 sub exch idiv             % number of pages
+               32 string cvs
+               /PageMaxString exch def
+
+               /HavePage 0 def                 % flag that page is built
+
+               HostStrings {
+                       aload pop               % put host strings on the stack
+                       HostCount HostMax eq {
+                               BuildPage       % time to build a new page
+                               /HavePage 1 def
+                       } if
+                       /HostCount HostCount 1 sub def
+                       BuildHost               % build this host line
+                       HostCount 0 le {
+                               *showpage       % time to dump a page
+                               /HavePage 0 def
+                               /HostCount HostMax def
+                       } if
+               } forall
+
+               HavePage 1 eq {
+                       *showpage               % dump the last page
+               } if
+       } def
+%%%
+% Normally there would be an "end" here to match the "begin" for our
+% dictionary, but we want to leave it on top of the dictionary stack
+% so the final showpage runs our showpage replacement.
+%%%
+
+%%%%
+%% END OF TEMPLATE FILE
+%%%% 
diff --git a/example/8.5x11.ps b/example/8.5x11.ps
new file mode 100644 (file)
index 0000000..5a90b7e
--- /dev/null
@@ -0,0 +1,253 @@
+%!
+%%BoundingBox: 25 25 290 900
+%%Title: AMANDA Full Page Label
+%%Creator: Amanda reporter
+%%Pages: 1
+%%EndComments
+
+%%%%
+%%%% This is a template file used by AMANDA to create 8.5 x 11 inch
+%%%% PostScript dump logs for each dump.
+%%%%
+
+%
+% The label is made up of 6 parts:  statistics, tape name, date,
+% header, filesystem list, and the logo.  Geometrically, the label 
+% looks like this:
+%
+%   +----+-------------------+
+%   |        TAPE_NAME       |   <- section 'A'
+%   | version  Location date |   <- section 'B'
+%   +------------------------+
+%   |statistics  |  message  |   <- section 'C' | 'F'
+%   +----+--+--------+-------+
+%   | f# hst fs lvl O-KB C-KB|   <- section 'D'
+%   +-------+--------+-------+
+%   |       |        |       |   <- section 'E'
+%   |       |        |       |
+%   v       v        v       v
+%
+
+% section 'A' font and position (text centered around this point)
+%
+/TitleFont             { /Helvetica-Bold findfont 24 scalefont setfont } def
+/TitlePos              { 321 728 } def
+
+% section 'B' font, position of the date (left justified) and the version
+%
+/DateFont              { /Palatino-Bold findfont 11 scalefont setfont } def
+/DatePos               { 580 715 } def
+/VersFont              { /Palatino-Bold findfont 11 scalefont setfont } def
+/VersPos               { 43 715 } def
+/LocFont               { /Helvetica-Bold findfont 12 scalefont setfont } def
+/LocPos                        { 321 715 } def
+
+% section 'C' font, start position, and line separation
+%
+/StatFont              { /Courier findfont 9 scalefont setfont } def
+/StatPos               { 43 695 } def
+/StatSep               { 9 } def
+
+% section 'D' font, and field positions (x coord is relative to each column)
+%
+
+/HeadingFont           { /Palatino-Bold findfont 9 scalefont setfont } def
+/HeadingFilePos                { 43 644 } def
+/HeadingHostPos                { 73 644 } def
+/HeadingFsPos          { 198 644 } def
+/HeadingLvlPos         { 333 644 } def
+/HeadingOSizePos1      { 403 652 } def
+/HeadingOSizePos       { 403 644 } def
+/HeadingCSizePos1      { 483 652 } def
+/HeadingCSizePos       { 483 644 } def
+
+
+% section 'E' font, and line separation
+%
+/HostFont              { /Courier findfont 9 scalefont setfont } def
+/HostSep               { 10 } def
+/HostBasePos           { 38 630 } def
+
+% section 'F' font, and line separation
+%
+/MessFont              { /Courier findfont 9 scalefont setfont } def
+/MessPos                { 215 702 } def
+/MessSep               { 9 } def
+
+
+% the following rectangles separate the regions
+%
+/TitleBox              { 590 750 38 710 } def
+/StatBox               { 590 710 38 660 } def
+/HeadingBox            { 590 660 38 640 } def
+/HostBox               { 590 640 38 0 } def
+/CFline                 { 208 710 208 660 } def
+
+
+
+
+%%%%
+%%%% END OF USER-CONFIGURABLE OPTIONS
+%%%%
+%%%% the rest of this file contains the internal functions that are used
+%%%% by genlabel to draw the label
+%%%%
+
+
+%
+% Initial Setup... draws everything that is the same for all labels
+%
+
+% function to draw a box
+%
+/box {
+       /ury exch def
+       /urx exch def
+       /lly exch def
+       /llx exch def
+
+       llx lly moveto
+       llx ury lineto
+       urx ury lineto
+       urx lly lineto
+       closepath
+} def
+
+
+% move the origin up a bit
+%
+0 20 translate
+
+% draw all of the boxes
+%
+0 setgray 
+2 setlinewidth                                 % thick lines
+StatBox box stroke
+TitleBox box stroke
+HeadingBox box stroke
+HostBox box stroke
+CFline moveto lineto stroke
+
+
+HeadingFont
+HeadingFilePos  moveto
+  (File #) show
+HeadingHostPos moveto
+  (Host) show
+HeadingFsPos moveto
+  (File System) show
+HeadingLvlPos moveto
+  (Level) stringwidth pop 2 div neg 0 rmoveto (Level) show
+HeadingOSizePos1 moveto
+  (Original) stringwidth pop 2 div neg 0 rmoveto (Original) show
+HeadingOSizePos moveto
+  (File Size (KB)) stringwidth pop 2 div neg 0 rmoveto (File Size (KB)) show
+HeadingCSizePos1 moveto
+  (Compressed) stringwidth pop 2 div neg 0 rmoveto (Compressed) show
+HeadingCSizePos moveto
+  (File Size (KB)) stringwidth pop 2 div neg 0 rmoveto (File Size (KB)) show
+
+
+%
+% the following functions draw strings for each kind of information
+%
+
+/CurrStatY StatPos exch pop def
+/CurrMessY MessPos exch pop def
+HostBasePos /CurrColumnY exch def
+/CurrColumnX exch def
+
+
+% DrawStat draws the string on the top of the stack in the next position
+% in section 'A'
+%
+/DrawStat {
+       StatFont
+       StatPos pop CurrStatY moveto
+       show
+       /CurrStatY CurrStatY StatSep sub def
+} def
+
+
+% DrawTitle draws the string on the top of the stack in section 'B'
+%
+/DrawTitle {
+       TitleFont
+       TitlePos moveto
+       dup stringwidth pop 2 div neg 0 rmoveto
+       show
+} def
+
+
+% DrawDate draws the string on the top of the stack in section 'C'
+%
+/DrawDate {
+       DateFont
+       DatePos moveto
+       dup stringwidth pop neg 0 rmoveto
+       show
+} def
+
+% DrawLoc draws the string on the top of the stack in section 'C'
+%
+/DrawLoc {
+       LocFont
+       LocPos moveto
+        dup stringwidth pop 2 div neg 0 rmoveto
+       show
+} def
+
+% DrawVers draws the string on the top of the stack in section 'C'
+%
+/DrawVers {
+       VersFont
+       VersPos moveto
+       show
+} def
+
+% DrawMess draws the string on the top of the stack in section 'F'
+%
+/DrawMess {
+        MessFont
+        MessPos pop CurrMessY moveto
+        show
+        /CurrMessY CurrMessY MessSep sub def
+} def
+
+% Fill in Location name and message
+%
+(Magic Software Development, Inc.) DrawLoc
+
+(To restore:) DrawMess
+(    position tape at the start of the file and run:) DrawMess
+(        dd if=/dev/nrst0 bs=32k skip=1 | zcat | restore -if -) DrawMess
+(    or run:) DrawMess
+(        amrestore -p /dev/nrst0 <host> <filesystem> | restore -if -) DrawMess
+
+
+% DrawHost expects six strings to be on the stack.  The strings are 
+% Host Name, Partition Name, Dump Level, Tape File Number, and Output Size.
+%
+/DrawHost {
+       HostFont
+        .25 setlinewidth                       % thin lines
+       HeadingCSizePos pop CurrColumnY moveto
+       -22 0 rmoveto show
+       HeadingOSizePos pop CurrColumnY moveto
+       -22 0 rmoveto show
+       HeadingFilePos pop CurrColumnY moveto
+       show
+       HeadingLvlPos pop CurrColumnY moveto
+       show
+       HeadingFsPos pop CurrColumnY moveto
+       show
+       HeadingHostPos pop CurrColumnY moveto
+       show
+        38 CurrColumnY 2.5 sub moveto 590 CurrColumnY 2.5 sub lineto stroke
+       /CurrColumnY CurrColumnY HostSep sub def
+} def
+
+
+%%%%
+%%%% END OF TEMPLATE FILE
+%%%% 
diff --git a/example/DIN-A4.ps b/example/DIN-A4.ps
new file mode 100644 (file)
index 0000000..e24c78d
--- /dev/null
@@ -0,0 +1,240 @@
+%!
+%%BoundingBox: 0 0 595 842
+%%Title: AMANDA ExaLabel
+%%Pages: 1
+%%EndComments
+
+%%%%
+%%%% This is a template file used by AMANDA to create PostScript tape
+%%%% labels for each dump.  This file is set up for DAT 4mm tapes,
+%%%% but you can edit it to work with anything.
+%%%%
+%%%% NOTE: this is quick-hack for DAT TAPES; it is simply a scaled 
+%%%% version of the Exabyte version.
+%%%%
+
+%
+% The label is made up of 6 parts:  statistics, tape name, date,
+% header, filesystem list, and the logo.  Geometrically, the label 
+% looks like this:
+%
+%   +------------------------+
+%   |statistics              |   <- section 'A'
+%   +----+-------------------+
+%   |logo|     TAPE_NAME     |   <- section 'B'  (logo) <- section 'F'
+%   |    | version      date |   <- section 'C'
+%   +----+--+--------+-------+
+%   | h   fs   l | h  fs   l |   <- section 'D'
+%   +-------+--------+-------+
+%   |            |           |   <- section 'E'
+%   |            |           |
+%   v            v           v
+%
+% Sections D and E, which hold the bulk of the information are 
+% cut into columns.
+%
+
+% Quick-hack for DAT tapes
+%
+
+72 25.4 div dup scale              %% scale to millimeters
+
+% section 'A' font, start position, and line separation
+%
+/StatFont              { /Courier findfont 4.5 scalefont setfont } def
+/StatPos               { 30 255 } def
+/StatSep               { 4 } def
+
+% section 'B' font and position (text centered around this point)
+%
+/TitleFont             { /Helvetica-Bold findfont 10 scalefont setfont } def
+/TitlePos              { 115 230 } def
+
+% section 'C' font, position of the date (left justified) and the version
+%
+/DateFont              { /Palatino-Bold findfont 5 scalefont setfont } def
+/DatePos               { 190 222 } def
+/VersFont              { /Palatino-Bold findfont 5 scalefont setfont } def
+/VersPos               { 43 222 } def
+
+% section 'D' font, and field positions (x coord is relative to each column)
+%
+
+/HeadingFont           { /Palatino-Bold findfont 5 scalefont setfont } def
+/HeadingHostPos                { 0 212 } def
+/HeadingFsPos          { 25 212 } def
+/HeadingLvlPos         { 110 212 } def
+
+% section 'E' font, and line separation
+%
+/HostFont              { /Courier findfont 4 scalefont setfont } def
+/HostSep               { 3.2 } def
+
+
+% the following rectangles separate the regions
+%
+/StatBox               { 200 260 15 240 } def
+/TitleBox              { 200 240 15 220 } def
+/LogoBox               { 35 240 15 220 } def
+/HeadingBox            { 200 220 15 210 } def
+/HostBox               { 200 210 15 0 } def
+
+
+% number of columns for section 'E,' column width, position of first 
+% entry in first column, y coordinate of top and bottom of dividing lines
+%
+/NumColumns            { 1 } def
+/ColumnWidth           { 132 } def
+/ColumnBasePos         { 25 190 } def
+/TopColDivLine         { 190 } def
+/BotColDivLine         { 0 } def
+
+
+%%%%
+%%%% END OF USER-CONFIGURABLE OPTIONS
+%%%%
+%%%% the rest of this file contains the internal functions that are used
+%%%% by genlabel to draw the label
+%%%%
+
+
+%
+% Initial Setup... draws everything that is the same for all labels
+%
+
+% function to draw a box
+%
+/box {
+       /ury exch def
+       /urx exch def
+       /lly exch def
+       /llx exch def
+
+       llx lly moveto
+       llx ury lineto
+       urx ury lineto
+       urx lly lineto
+       closepath
+} def
+
+
+% move the origin up a bit
+%
+0 20 translate
+
+% draw all of the boxes
+%
+0 setgray 
+.3 setlinewidth                                        % thick lines
+StatBox box stroke
+TitleBox box stroke
+LogoBox box stroke
+HeadingBox box stroke
+HostBox box stroke
+
+
+% draw the column dividers
+%
+0.5 setlinewidth                               % thin lines
+/i 1 def
+{
+       NumColumns i sub 0 le { exit } if       % no lines if this last col.
+       /xoff ColumnBasePos pop                 % get x base position
+          i ColumnWidth mul add def            % offset for this column
+       xoff TopColDivLine moveto 
+       xoff BotColDivLine lineto stroke        
+       /i i 1 add def
+} loop
+
+
+% draw the heading names
+%
+/i 0 def
+HeadingFont
+{
+       NumColumns i sub 0 le { exit } if
+       /xoff ColumnBasePos pop
+         i ColumnWidth mul add def
+       HeadingHostPos exch xoff add exch moveto
+         (Host) show
+       HeadingFsPos exch xoff add exch moveto
+         (Fs) show
+       HeadingLvlPos exch xoff add exch moveto
+         (Lv) show
+       /i i 1 add def
+} loop
+
+
+%
+% the following functions draw strings for each kind of information
+%
+
+/CurrStatY StatPos exch pop def
+ColumnBasePos /CurrColumnY exch def
+  /CurrColumnX exch def
+
+
+% DrawStat draws the string on the top of the stack in the next position
+% in section 'A'
+%
+/DrawStat {
+       StatFont
+       StatPos pop CurrStatY moveto
+       show
+       /CurrStatY CurrStatY StatSep sub def
+} def
+
+
+% DrawTitle draws the string on the top of the stack in section 'B'
+%
+/DrawTitle {
+       TitleFont
+       TitlePos moveto
+       dup stringwidth pop 2 div neg 0 rmoveto
+       show
+} def
+
+
+% DrawDate draws the string on the top of the stack in section 'C'
+%
+/DrawDate {
+       DateFont
+       DatePos moveto
+       dup stringwidth pop neg 0 rmoveto
+       show
+} def
+
+
+% DrawVers draws the string on the top of the stack in section 'C'
+%
+/DrawVers {
+       VersFont
+       VersPos moveto
+       show
+} def
+
+
+% DrawHost expects five strings to be on the stack; right now it
+% uses only the first three.  The strings are Host Name, Partition Name,
+% Dump Level, Tape File Number, and Output Size.
+% 
+/DrawHost {
+       HostFont
+       pop pop pop                     % discard sizes and fileno
+       CurrColumnX HeadingLvlPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingFsPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingHostPos pop add CurrColumnY moveto
+       show
+       /CurrColumnY CurrColumnY HostSep sub def
+       CurrColumnY BotColDivLine lt {
+               /CurrColumnY ColumnBasePos exch pop def
+               /CurrColumnX CurrColumnX ColumnWidth add def
+       } if
+} def
+
+
+%%%%
+%%%% END OF TEMPLATE FILE
+%%%% 
diff --git a/example/DLT.ps b/example/DLT.ps
new file mode 100644 (file)
index 0000000..84b574c
--- /dev/null
@@ -0,0 +1,232 @@
+%!
+%%BoundingBox: 25 25 290 900
+%%Title: AMANDA ExaLabel
+%%Creator: AMANDA genlabel program
+%%Pages: 1
+%%EndComments
+
+%%%%
+%%%% This is a template file used by AMANDA to create PostScript tape
+%%%% labels for each dump.  This file is set up for DLT tapes,
+%%%% but you can edit it to work with anything.
+%%%%
+
+
+%
+% The label is made up of 6 parts:  statistics, tape name, date,
+% header, filesystem list, and the logo.  Geometrically, the label
+% looks like this:
+%
+%   +------------------------+
+%   |statistics              |   <- section 'A'
+%   +----+-------------------+
+%   |logo|     TAPE_NAME     |   <- section 'B'  (logo) <- section 'F'
+%   |    | version      date |   <- section 'C'
+%   +----+--+--------+-------+
+%   |h fs  l|h fs   l|h fs  l|   <- section 'D'
+%   +-------+--------+-------+
+%   |       |        |       |   <- section 'E'
+%   |       |        |       |
+%   v       v        v       v
+%
+% Sections D and E, which hold the bulk of the information are 
+% cut into columns.
+%
+
+% section 'A' font, start position, and line separation
+%
+/StatFont              { /Courier findfont 10 scalefont setfont } def
+/StatPos               { 40 738 } def
+/StatSep               { 15 } def
+
+% section 'B' font and position (text centered around this point)
+%
+/TitleFont             { /Helvetica-Bold findfont 28 scalefont setfont } def
+/TitlePos              { 180 635 } def
+
+% section 'C' font, position of the date (left justified) and the version
+%
+/DateFont              { /Palatino-Bold findfont 10 scalefont setfont } def
+/DatePos               { 310 610 } def
+/VersFont              { /Palatino-Bold findfont 10 scalefont setfont } def
+/VersPos               { 80 610 } def
+
+% section 'D' font, and field positions (x coord is relative to each column)
+%
+
+/HeadingFont           { /Palatino-Bold findfont 8 scalefont setfont } def
+/HeadingLvlPos         { 90 590 } def          % Heading is right justified
+/HeadingHostPos                { 2 590 } def
+/HeadingFsPos          { 30 590 } def
+
+% section 'E' font, and line separation
+%
+/HostFont              { /Courier findfont 5 scalefont setfont } def
+/HostSep               { 5 } def
+
+
+% the following rectangles separate the regions
+%
+/StatBox               { 320 755 25 680 } def
+/TitleBox              { 320 680 25 605 } def
+/LogoBox               { 70 680 25 605 } def
+/HeadingBox            { 320 605 25 580 } def
+/HostBox               { 320 580 25 0 } def
+
+
+% number of columns for section 'E,' column width, position of first 
+% entry in first column, y coordinate of top and bottom of dividing lines
+%
+/NumColumns            { 3 } def
+/ColumnWidth           { 98 } def
+/ColumnBasePos         { 25 568 } def
+/TopColDivLine         { 605 } def
+/BotColDivLine         { 0 } def
+
+
+%%%%
+%%%% END OF USER-CONFIGURABLE OPTIONS
+%%%%
+%%%% the rest of this file contains the internal functions that are used
+%%%% by genlabel to draw the label
+%%%%
+
+
+%
+% Initial Setup... draws everything that is the same for all labels
+%
+
+% function to draw a box
+%
+/box {
+       /ury exch def
+       /urx exch def
+       /lly exch def
+       /llx exch def
+
+       llx lly moveto
+       llx ury lineto
+       urx ury lineto
+       urx lly lineto
+       closepath
+} def
+
+
+% move the origin up a bit
+%
+0 20 translate
+
+% draw all of the boxes
+%
+0 setgray 
+2 setlinewidth                                 % thick lines
+StatBox box stroke
+TitleBox box stroke
+LogoBox box stroke
+HeadingBox box stroke
+HostBox box stroke
+
+% draw the column dividers
+%
+0.5 setlinewidth                               % thin lines
+
+/i 1 def
+{
+       NumColumns i sub 0 le { exit } if       % no lines if this last col.
+       /xoff ColumnBasePos pop                 % get x base position
+          i ColumnWidth mul add def            % offset for this column
+       xoff TopColDivLine moveto 
+       xoff BotColDivLine lineto stroke        
+       /i i 1 add def
+} loop
+
+
+% draw the heading names
+%
+/i 0 def
+HeadingFont
+{
+       NumColumns i sub 0 le { exit } if
+       /xoff ColumnBasePos pop
+         i ColumnWidth mul add def
+       HeadingLvlPos exch xoff add exch moveto
+         (Lv) stringwidth pop neg 0 rmoveto (Lv) show
+       HeadingHostPos exch xoff add exch moveto
+         (Host) show
+       HeadingFsPos exch xoff add exch moveto
+         (Fs) show
+       /i i 1 add def
+} loop
+
+
+%
+% the following functions draw strings for each kind of information
+%
+
+/CurrStatY StatPos exch pop def
+ColumnBasePos /CurrColumnY exch def
+  /CurrColumnX exch def
+
+
+% DrawStat draws the string on the top of the stack in the next position
+% in section 'A'
+%
+/DrawStat {
+       StatFont
+       StatPos pop CurrStatY moveto
+       show
+       /CurrStatY CurrStatY StatSep sub def
+} def
+
+
+% DrawTitle draws the string on the top of the stack in section 'B'
+%
+/DrawTitle {
+       TitleFont
+       TitlePos moveto
+       dup stringwidth pop 2 div neg 0 rmoveto
+       show
+} def
+
+
+% DrawDate draws the string on the top of the stack in section 'C'
+%
+/DrawDate {
+       DateFont
+       DatePos moveto
+       dup stringwidth pop neg 0 rmoveto
+       show
+} def
+
+
+% DrawVers draws the string on the top of the stack in section 'C'
+%
+/DrawVers {
+       VersFont
+       VersPos moveto
+       show
+} def
+
+
+% DrawHost expects five strings to be on the stack.  The strings are 
+% Host Name, Partition Name, Dump Level, Tape File Number, and Output Size.
+% Right now, the Output Size and file umber are discarded.
+%
+/DrawHost {
+       HostFont
+       pop pop pop                     % discard sizes and fileno
+       CurrColumnX HeadingLvlPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingFsPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingHostPos pop add CurrColumnY moveto
+       show
+       /CurrColumnY CurrColumnY HostSep sub def
+       CurrColumnY BotColDivLine lt {
+               /CurrColumnY ColumnBasePos exch pop def
+               /CurrColumnX CurrColumnX ColumnWidth add def
+       } if
+} def
+%%%%
+%%%% END OF TEMPLATE FILE
+%%%% 
diff --git a/example/EXB-8500.ps b/example/EXB-8500.ps
new file mode 100644 (file)
index 0000000..e5a7261
--- /dev/null
@@ -0,0 +1,233 @@
+%!
+%%BoundingBox: 25 25 290 900
+%%Title: AMANDA ExaLabel
+%%Creator: AMANDA genlabel program
+%%Pages: 1
+%%EndComments
+
+%%%%
+%%%% This is a template file used by AMANDA to create PostScript tape
+%%%% labels for each dump.  This file is set up for Exabyte 8mm tapes,
+%%%% but you can edit it to work with anything.
+%%%%
+
+%
+% The label is made up of 6 parts:  statistics, tape name, date,
+% header, filesystem list, and the logo.  Geometrically, the label 
+% looks like this:
+%
+%   +------------------------+
+%   |statistics              |   <- section 'A'
+%   +----+-------------------+
+%   |logo|     TAPE_NAME     |   <- section 'B'  (logo) <- section 'F'
+%   |    | version      date |   <- section 'C'
+%   +----+--+--------+-------+
+%   | h fs l| h fs l | h fs l|   <- section 'D'
+%   +-------+--------+-------+
+%   |       |        |       |   <- section 'E'
+%   |       |        |       |
+%   v       v        v       v
+%
+% Sections D and E, which hold the bulk of the information are 
+% cut into columns.
+%
+
+% section 'A' font, start position, and line separation
+%
+/StatFont              { /Courier findfont 9 scalefont setfont } def
+/StatPos               { 40 740 } def
+/StatSep               { 8 } def
+
+% section 'B' font and position (text centered around this point)
+%
+/TitleFont             { /Helvetica-Bold findfont 24 scalefont setfont } def
+/TitlePos              { 180 685 } def
+
+% section 'C' font, position of the date (left justified) and the version
+%
+/DateFont              { /Palatino-Bold findfont 10 scalefont setfont } def
+/DatePos               { 280 670 } def
+/VersFont              { /Palatino-Bold findfont 10 scalefont setfont } def
+/VersPos               { 80 670 } def
+
+% section 'D' font, and field positions (x coord is relative to each column)
+%
+
+/HeadingFont           { /Palatino-Bold findfont 8 scalefont setfont } def
+/HeadingLvlPos         { 126 650 } def         % Heading is right justified
+/HeadingHostPos                { 5 650 } def
+/HeadingFsPos          { 45 650 } def
+
+% section 'E' font, and line separation
+%
+/HostFont              { /Courier findfont 6 scalefont setfont } def
+/HostSep               { 6 } def
+
+
+% the following rectangles separate the regions
+%
+/StatBox               { 290 750 25 710 } def
+/TitleBox              { 290 710 25 665 } def
+/LogoBox               { 70 710 25 665 } def
+/HeadingBox            { 290 665 25 645 } def
+/HostBox               { 290 645 25 0 } def
+
+
+% number of columns for section 'E,' column width, position of first 
+% entry in first column, y coordinate of top and bottom of dividing lines
+%
+/NumColumns            { 2 } def
+/ColumnWidth           { 132 } def
+/ColumnBasePos         { 25 633 } def
+/TopColDivLine         { 665 } def
+/BotColDivLine         { 0 } def
+
+
+%%%%
+%%%% END OF USER-CONFIGURABLE OPTIONS
+%%%%
+%%%% the rest of this file contains the internal functions that are used
+%%%% by genlabel to draw the label
+%%%%
+
+
+%
+% Initial Setup... draws everything that is the same for all labels
+%
+
+% function to draw a box
+%
+/box {
+       /ury exch def
+       /urx exch def
+       /lly exch def
+       /llx exch def
+
+       llx lly moveto
+       llx ury lineto
+       urx ury lineto
+       urx lly lineto
+       closepath
+} def
+
+
+% move the origin up a bit
+%
+0 20 translate
+
+% draw all of the boxes
+%
+0 setgray 
+2 setlinewidth                                 % thick lines
+StatBox box stroke
+TitleBox box stroke
+LogoBox box stroke
+HeadingBox box stroke
+HostBox box stroke
+
+
+% draw the column dividers
+%
+0.5 setlinewidth                               % thin lines
+/i 1 def
+{
+       NumColumns i sub 0 le { exit } if       % no lines if this last col.
+       /xoff ColumnBasePos pop                 % get x base position
+          i ColumnWidth mul add def            % offset for this column
+       xoff TopColDivLine moveto 
+       xoff BotColDivLine lineto stroke        
+       /i i 1 add def
+} loop
+
+
+% draw the heading names
+%
+/i 0 def
+HeadingFont
+{
+       NumColumns i sub 0 le { exit } if
+       /xoff ColumnBasePos pop
+         i ColumnWidth mul add def
+       HeadingLvlPos exch xoff add exch moveto
+         (Lv) stringwidth pop neg 0 rmoveto (Lv) show
+       HeadingHostPos exch xoff add exch moveto
+         (Host) show
+       HeadingFsPos exch xoff add exch moveto
+         (Fs) show
+       /i i 1 add def
+} loop
+
+
+%
+% the following functions draw strings for each kind of information
+%
+
+/CurrStatY StatPos exch pop def
+ColumnBasePos /CurrColumnY exch def
+  /CurrColumnX exch def
+
+
+% DrawStat draws the string on the top of the stack in the next position
+% in section 'A'
+%
+/DrawStat {
+       StatFont
+       StatPos pop CurrStatY moveto
+       show
+       /CurrStatY CurrStatY StatSep sub def
+} def
+
+
+% DrawTitle draws the string on the top of the stack in section 'B'
+%
+/DrawTitle {
+       TitleFont
+       TitlePos moveto
+       dup stringwidth pop 2 div neg 0 rmoveto
+       show
+} def
+
+
+% DrawDate draws the string on the top of the stack in section 'C'
+%
+/DrawDate {
+       DateFont
+       DatePos moveto
+       dup stringwidth pop neg 0 rmoveto
+       show
+} def
+
+
+% DrawVers draws the string on the top of the stack in section 'C'
+%
+/DrawVers {
+       VersFont
+       VersPos moveto
+       show
+} def
+
+
+% DrawHost expects five strings to be on the stack.  The strings are 
+% Host Name, Partition Name, Dump Level, Tape File Number, and Output Size.
+% Right now, the Output Size is discarded.
+%
+/DrawHost {
+       HostFont
+       pop pop pop                     % discard sizes and fileno
+       CurrColumnX HeadingLvlPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingFsPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingHostPos pop add CurrColumnY moveto
+       show
+       /CurrColumnY CurrColumnY HostSep sub def
+       CurrColumnY BotColDivLine lt {
+               /CurrColumnY ColumnBasePos exch pop def
+               /CurrColumnX CurrColumnX ColumnWidth add def
+       } if
+} def
+
+
+%%%%
+%%%% END OF TEMPLATE FILE
+%%%% 
diff --git a/example/HP-DAT.ps b/example/HP-DAT.ps
new file mode 100644 (file)
index 0000000..f0cf6b5
--- /dev/null
@@ -0,0 +1,239 @@
+%!
+%%BoundingBox: 25 25 290 900
+%%Title: AMANDA ExaLabel
+%%Pages: 1
+%%EndComments
+
+%%%%
+%%%% This is a template file used by AMANDA to create PostScript tape
+%%%% labels for each dump.  This file is set up for DAT 4mm tapes,
+%%%% but you can edit it to work with anything.
+%%%%
+%%%% NOTE: this is quick-hack for DAT TAPES; it is simply a scaled 
+%%%% version of the Exabyte version.
+%%%%
+
+%
+% The label is made up of 6 parts:  statistics, tape name, date,
+% header, filesystem list, and the logo.  Geometrically, the label 
+% looks like this:
+%
+%   +------------------------+
+%   |statistics              |   <- section 'A'
+%   +----+-------------------+
+%   |logo|     TAPE_NAME     |   <- section 'B'  (logo) <- section 'F'
+%   |    | version      date |   <- section 'C'
+%   +----+--+--------+-------+
+%   | h   fs   l | h  fs   l |   <- section 'D'
+%   +-------+--------+-------+
+%   |            |           |   <- section 'E'
+%   |            |           |
+%   v            v           v
+%
+% Sections D and E, which hold the bulk of the information are 
+% cut into columns.
+%
+
+% Quick-hack for DAT tapes
+%
+.78 .75 scale
+
+% section 'A' font, start position, and line separation
+%
+/StatFont              { /Courier findfont 9 scalefont setfont } def
+/StatPos               { 40 740 } def
+/StatSep               { 8 } def
+
+% section 'B' font and position (text centered around this point)
+%
+/TitleFont             { /Helvetica-Bold findfont 24 scalefont setfont } def
+/TitlePos              { 180 685 } def
+
+% section 'C' font, position of the date (left justified) and the version
+%
+/DateFont              { /Palatino-Bold findfont 10 scalefont setfont } def
+/DatePos               { 280 670 } def
+/VersFont              { /Palatino-Bold findfont 10 scalefont setfont } def
+/VersPos               { 80 670 } def
+
+% section 'D' font, and field positions (x coord is relative to each column)
+%
+
+/HeadingFont           { /Palatino-Bold findfont 8 scalefont setfont } def
+/HeadingHostPos                { 5 650 } def
+/HeadingFsPos          { 45 650 } def
+/HeadingLvlPos         { 120 650 } def
+
+% section 'E' font, and line separation
+%
+/HostFont              { /Courier findfont 6 scalefont setfont } def
+/HostSep               { 6 } def
+
+
+% the following rectangles separate the regions
+%
+/StatBox               { 290 750 25 710 } def
+/TitleBox              { 290 710 25 665 } def
+/LogoBox               { 70 710 25 665 } def
+/HeadingBox            { 290 665 25 645 } def
+/HostBox               { 290 645 25 0 } def
+
+
+% number of columns for section 'E,' column width, position of first 
+% entry in first column, y coordinate of top and bottom of dividing lines
+%
+/NumColumns            { 2 } def
+/ColumnWidth           { 132 } def
+/ColumnBasePos         { 25 633 } def
+/TopColDivLine         { 665 } def
+/BotColDivLine         { 0 } def
+
+
+%%%%
+%%%% END OF USER-CONFIGURABLE OPTIONS
+%%%%
+%%%% the rest of this file contains the internal functions that are used
+%%%% by genlabel to draw the label
+%%%%
+
+
+%
+% Initial Setup... draws everything that is the same for all labels
+%
+
+% function to draw a box
+%
+/box {
+       /ury exch def
+       /urx exch def
+       /lly exch def
+       /llx exch def
+
+       llx lly moveto
+       llx ury lineto
+       urx ury lineto
+       urx lly lineto
+       closepath
+} def
+
+
+% move the origin up a bit
+%
+0 20 translate
+
+% draw all of the boxes
+%
+0 setgray 
+2 setlinewidth                                 % thick lines
+StatBox box stroke
+TitleBox box stroke
+LogoBox box stroke
+HeadingBox box stroke
+HostBox box stroke
+
+
+% draw the column dividers
+%
+0.5 setlinewidth                               % thin lines
+/i 1 def
+{
+       NumColumns i sub 0 le { exit } if       % no lines if this last col.
+       /xoff ColumnBasePos pop                 % get x base position
+          i ColumnWidth mul add def            % offset for this column
+       xoff TopColDivLine moveto 
+       xoff BotColDivLine lineto stroke        
+       /i i 1 add def
+} loop
+
+
+% draw the heading names
+%
+/i 0 def
+HeadingFont
+{
+       NumColumns i sub 0 le { exit } if
+       /xoff ColumnBasePos pop
+         i ColumnWidth mul add def
+       HeadingHostPos exch xoff add exch moveto
+         (Host) show
+       HeadingFsPos exch xoff add exch moveto
+         (Fs) show
+       HeadingLvlPos exch xoff add exch moveto
+         (Lv) show
+       /i i 1 add def
+} loop
+
+
+%
+% the following functions draw strings for each kind of information
+%
+
+/CurrStatY StatPos exch pop def
+ColumnBasePos /CurrColumnY exch def
+  /CurrColumnX exch def
+
+
+% DrawStat draws the string on the top of the stack in the next position
+% in section 'A'
+%
+/DrawStat {
+       StatFont
+       StatPos pop CurrStatY moveto
+       show
+       /CurrStatY CurrStatY StatSep sub def
+} def
+
+
+% DrawTitle draws the string on the top of the stack in section 'B'
+%
+/DrawTitle {
+       TitleFont
+       TitlePos moveto
+       dup stringwidth pop 2 div neg 0 rmoveto
+       show
+} def
+
+
+% DrawDate draws the string on the top of the stack in section 'C'
+%
+/DrawDate {
+       DateFont
+       DatePos moveto
+       dup stringwidth pop neg 0 rmoveto
+       show
+} def
+
+
+% DrawVers draws the string on the top of the stack in section 'C'
+%
+/DrawVers {
+       VersFont
+       VersPos moveto
+       show
+} def
+
+
+% DrawHost expects five strings to be on the stack; right now it
+% uses only the first three.  The strings are Host Name, Partition Name,
+% Dump Level, Tape File Number, and Output Size.
+% 
+/DrawHost {
+       HostFont
+       pop pop pop                     % discard sizes and fileno
+       CurrColumnX HeadingLvlPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingFsPos pop add CurrColumnY moveto
+       show
+       CurrColumnX HeadingHostPos pop add CurrColumnY moveto
+       show
+       /CurrColumnY CurrColumnY HostSep sub def
+       CurrColumnY BotColDivLine lt {
+               /CurrColumnY ColumnBasePos exch pop def
+               /CurrColumnX CurrColumnX ColumnWidth add def
+       } if
+} def
+
+
+%%%%
+%%%% END OF TEMPLATE FILE
+%%%% 
diff --git a/example/Makefile.am b/example/Makefile.am
new file mode 100644 (file)
index 0000000..1d1cd56
--- /dev/null
@@ -0,0 +1,7 @@
+# Makefile for sample configuration files
+
+noinst_DATA = amanda.conf amanda.conf.chg-scsi
+
+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
diff --git a/example/Makefile.in b/example/Makefile.in
new file mode 100644 (file)
index 0000000..7b952e0
--- /dev/null
@@ -0,0 +1,427 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 sample configuration files
+
+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 = :
+host_triplet = @host@
+subdir = example
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+       $(srcdir)/amanda.conf.chg-scsi.in $(srcdir)/amanda.conf.in \
+       $(srcdir)/chg-mcutil.conf.in $(srcdir)/chg-scsi-hpux.conf.in \
+       $(srcdir)/chg-scsi-linux.conf.in \
+       $(srcdir)/chg-scsi-solaris.conf.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 = amanda.conf amanda.conf.chg-scsi \
+       chg-scsi-linux.conf chg-scsi-solaris.conf chg-scsi-hpux.conf \
+       chg-mcutil.conf
+SOURCES =
+DIST_SOURCES =
+DATA = $(noinst_DATA)
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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@
+noinst_DATA = amanda.conf amanda.conf.chg-scsi
+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
+
+all: all-am
+
+.SUFFIXES:
+$(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  example/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  example/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
+amanda.conf: $(top_builddir)/config.status $(srcdir)/amanda.conf.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amanda.conf.chg-scsi: $(top_builddir)/config.status $(srcdir)/amanda.conf.chg-scsi.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-scsi-linux.conf: $(top_builddir)/config.status $(srcdir)/chg-scsi-linux.conf.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-scsi-solaris.conf: $(top_builddir)/config.status $(srcdir)/chg-scsi-solaris.conf.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+chg-scsi-hpux.conf: $(top_builddir)/config.status $(srcdir)/chg-scsi-hpux.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)/$@
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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 $(DATA)
+installdirs:
+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:
+       -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-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-libtool distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-exec install-exec-am \
+       install-info install-info-am install-man install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+       uninstall-info-am
+
+# 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/example/amanda.conf.chg-scsi.in b/example/amanda.conf.chg-scsi.in
new file mode 100644 (file)
index 0000000..a4cefc0
--- /dev/null
@@ -0,0 +1,524 @@
+###  !!! 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.  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
+dumpuser "@CLIENT_LOGIN@"      # the user to run dumps under
+
+inparallel 4           # maximum dumpers that will run in parallel (max 63)
+                       # this maximum can be increased at compile-time,
+                       # modifying MAX_DUMPERS in server-src/driverio.h
+netusage  600 Kbps     # maximum net bandwidth for Amanda, in KB per sec
+
+dumpcycle 4 weeks      # the number of days in the normal dump cycle
+runspercycle 20         # the number of amdump runs in dumpcycle days
+                       # (4 weeks * 5 amdump runs per week -- just weekdays)
+tapecycle 25 tapes     # the number of tapes in rotation
+                       # 4 weeks (dumpcycle) times 5 tapes per week (just
+                       # the weekdays) plus a few to handle errors that
+                       # need amflush and so we do not overwrite the full
+                       # backups performed at the beginning of the previous
+                       # cycle
+### ### ###
+# WARNING: don't use `inf' for tapecycle, it's broken!
+### ### ###
+
+bumpsize 20 Mb         # minimum savings (threshold) to bump level 1 -> 2
+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).
+
+
+# Specify tape device and/or tape changer.  If you don't have a tape
+# changer, and you don't want to use more than one tape per run of
+# amdump, just comment out the definition of tpchanger.
+
+# Some tape changers require tapedev to be defined; others will use
+# their own tape device selection mechanism.  Some use a separate tape
+# changer device (changerdev), others will simply ignore this
+# 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.
+
+# 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-scsi"   # the tape-changer glue script
+tapedev "0"    # the no-rewind tape device to be used
+changerfile "@CONFIG_DIR@/@DEFAULT_CONFIG@/chg-scsi.conf"
+
+tapetype HP-DAT                # what kind of tape it is (see tapetypes below)
+labelstr "^@DEFAULT_CONFIG@[0-9][0-9]*$"       # label constraint regex: all tapes must match
+
+# Specify holding disks.  These are used as a temporary staging area for
+# dumps before they are written to tape and are recommended for most sites.
+# The advantages include: tape drive is more likely to operate in streaming
+# mode (which reduces tape and drive wear, reduces total dump time); multiple
+# dumps can be done in parallel (which can dramatically reduce total dump time.
+# The main disadvantage is that dumps on the holding disk need to be flushed
+# (with amflush) to tape after an operating system crash or a tape failure.
+# If no holding disks are specified then all dumps will be written directly
+# to tape.  If a dump is too big to fit on the holding disk than it will be
+# written directly to tape.  If more than one holding disk is specified then
+# they will all be used based on activity and available space.
+
+holdingdisk hd1 {
+    comment "main holding disk"
+    directory "/dumps/amanda"  # where the holding disk is
+    use 290 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
+                       #             The maximum value should be
+                       #             (MAX_FILE_SIZE - 1Mb)
+                       #  0          same as INT_MAX bytes
+    }
+#holdingdisk hd2 {
+#    directory "/dumps2/amanda"
+#    use 1000 Mb
+#    }
+#holdingdisk hd3 {
+#    directory "/mnt/disk4"
+#    use 1000 Mb
+#    }
+
+
+# If amanda cannot find a tape on which to store backups, it will run
+# as many backups as it can to the holding disks.  In order to save
+# space for unattended backups, by default, amanda will only perform
+# incremental backups in this case, i.e., it will reserve 100% of the
+# holding disk space for the so-called degraded mode backups.
+# However, if you specify a different value for the `reserve'
+# parameter, amanda will not degrade backups if they will fit in the
+# non-reserved portion of the holding disk.
+
+# reserve 30 # percent
+# This means save at least 30% of the holding disk space for degraded
+# mode backups.  
+
+# The format for a ColumnSpec is a ',' seperated list of triples.
+# Each triple consists of
+#   + the name of the column (as in ColumnNameStrings)
+#   + prefix before the column
+#   + the width of the column, if set to -1 it will be recalculated
+#     to the maximum length of a line to print.
+# Example:
+#      "Disk=1:17,HostName=1:10,OutKB=1:7"
+# or
+#      "Disk=1:-1,HostName=1:10,OutKB=1:7"
+#        
+# You need only specify those colums that should be changed from
+# the default. If nothing is specified in the configfile, the
+# above compiled in values will be in effect, resulting in an
+# output as it was all the time.
+# The names of the colums are:
+# HostName, Disk, Level, OrigKB, OutKB, Compress, DumpTime, DumpRate,
+# TapeTime and TapeRate.
+#                                                      ElB, 1999-02-24.
+# columnspec "Disk=1:18,HostName=0:10,OutKB=1:7"
+
+
+# Amanda needs a few Mb of diskspace for the log and debug files,
+# as well as a database.  This stuff can grow large, so the conf directory
+# isn't usually appropriate.  Some sites use /usr/local/var and some /usr/adm.
+# Create an amanda directory under there.  You need a separate infofile and
+# logdir for each configuration, so create subdirectories for each conf and
+# put the files there.  Specify the locations below.
+
+# Note that, although the keyword below is infofile, it is only so for
+# historic reasons, since now it is supposed to be a directory (unless
+# you have selected some database format other than the `text' default)
+infofile "/usr/adm/amanda/@DEFAULT_CONFIG@/curinfo"    # database DIRECTORY
+logdir   "/usr/adm/amanda/@DEFAULT_CONFIG@"            # log directory
+indexdir "/usr/adm/amanda/@DEFAULT_CONFIG@/index"      # index directory
+#tapelist "/usr/adm/amanda/@DEFAULT_CONFIG@/tapelist"  # list of used tapes
+# tapelist is stored, by default, in the directory that contains amanda.conf
+
+
+# tapetypes
+
+# Define the type of tape you use here, and use it in "tapetype"
+# above.  Some typical types of tapes are included here.  The tapetype
+# tells amanda how many MB will fit on the tape, how big the filemarks
+# are, and how fast the tape device is.
+
+# A filemark is the amount of wasted space every time a tape section
+# ends.  If you run `make tapetype' in tape-src, you'll get a program
+# that generates tapetype entries, but it is slow as hell, use it only
+# if you really must and, if you do, make sure you post the data to
+# the amanda mailing list, so that others can use what you found out
+# by searching the archives.
+
+# For completeness Amanda should calculate the inter-record gaps too,
+# but it doesn't.  For EXABYTE and DAT tapes this is ok.  Anyone using
+# 9 tracks for amanda and need IRG calculations?  Drop me a note if
+# so.
+
+# If you want amanda to print postscript paper tape labels
+# add a line after the comment in the tapetype of the form
+#    lbl-templ "/path/to/postscript/template/label.ps"
+
+# if you want the label to go to a printer other than the default
+# for your system, you can also add a line above for a different
+# printer. (i usually add that line after the dumpuser specification)
+
+# dumpuser "operator"     # the user to run dumps under
+# printer "mypostscript"  # printer to print paper label on
+
+# here is an example of my definition for an EXB-8500
+
+# define tapetype EXB-8500 {
+# ...
+#     lbl-templ "/usr/local/amanda/config/lbl.exabyte.ps"
+# }
+
+
+define tapetype QIC-60 {
+    comment "Archive Viper"
+    length 60 mbytes
+    filemark 100 kbytes                # don't know a better value
+    speed 100 kbytes           # dito
+}
+
+define tapetype DEC-DLT2000 {
+    comment "DEC Differential Digital Linear Tape 2000"
+    length 15000 mbytes
+    filemark 8 kbytes
+    speed 1250 kbytes
+}
+
+# goluboff@butch.Colorado.EDU
+# in amanda-users (Thu Dec 26 01:55:38 MEZ 1996)
+define tapetype DLT {
+    comment "DLT tape drives"
+    length 20000 mbytes                # 20 Gig tapes
+    filemark 2000 kbytes       # I don't know what this means
+    speed 1536 kbytes          # 1.5 Mb/s
+}
+
+define tapetype SURESTORE-1200E {
+    comment "HP AutoLoader"
+    length 3900 mbytes
+    filemark 100 kbytes
+    speed 500 kbytes
+}
+
+define tapetype EXB-8500 {
+    comment "Exabyte EXB-8500 drive on decent machine"
+    length 4200 mbytes
+    filemark 48 kbytes
+    speed 474 kbytes                   
+}
+
+define tapetype EXB-8200 {
+    comment "Exabyte EXB-8200 drive on decent machine"
+    length 2200 mbytes
+    filemark 2130 kbytes
+    speed 240 kbytes                   
+}
+
+define tapetype HP-DAT {
+    comment "DAT tape drives"
+    # data provided by Rob Browning <rlb@cs.utexas.edu>
+    length 1930 mbytes
+    filemark 111 kbytes
+    speed 468 kbytes
+}
+
+define tapetype DAT {
+    comment "DAT tape drives"
+    length 1000 mbytes         # these numbers are not accurate
+    filemark 100 kbytes                # but you get the idea
+    speed 100 kbytes
+}
+
+define tapetype MIMSY-MEGATAPE {
+    comment "Megatape (Exabyte based) drive through Emulex on Vax 8600"
+    length 2200 mbytes
+    filemark 2130 kbytes
+    speed 170 kbytes           # limited by the Emulex bus interface, ugh
+}
+
+
+# dumptypes
+#
+# These are referred to by the disklist file.  The dumptype specifies
+# certain parameters for dumping including:
+#   auth       - authentication scheme to use between server and client.
+#                Valid values are "bsd" and "krb4".  Default: [auth bsd]
+#   comment    - just a comment string
+#   comprate   - set default compression rate.  Should be followed by one or
+#                two numbers, optionally separated by a comma.  The 1st is
+#                the full compression rate; the 2nd is the incremental rate.
+#                If the second is omitted, it is assumed equal to the first.
+#                The numbers represent the amount of the original file the
+#                compressed file is expected to take up.
+#                Default: [comprate 0.50, 0.50]
+#   compress   - specify compression of the backed up data.  Valid values are:
+#                "none"        - don't compress the dump output.
+#                "client best" - compress on the client using the best (and
+#                                probably slowest) algorithm.
+#                "client fast" - compress on the client using fast algorithm.
+#                "server best" - compress on the tape host using the best (and
+#                                probably slowest) algorithm.
+#                "server fast" - compress on the tape host using a fast
+#                                algorithm.  This may be useful when a fast
+#                                tape host is backing up slow clients.
+#                Default: [compress client fast]
+#   dumpcycle  - set the number of days in the dump cycle, ie, set how often a
+#                full dump should be performed.  Default: from DUMPCYCLE above
+#   exclude    - specify files and directories to be excluded from the dump.
+#                Useful with gnutar only; silently ignored by dump and samba.
+#                Valid values are:
+#                "pattern"       - a shell glob pattern defining which files
+#                                  to exclude.
+#                                  gnutar gets --exclude="pattern"
+#                list "filename" - a file (on the client!) containing patterns
+#                                  re's (1 per line) defining which files to
+#                                  exclude.
+#                                  gnutar gets --exclude-from="filename"
+#                Note that the `full pathname' of a file within its
+#                filesystem starts with `./', because of the way amanda runs
+#                gnutar: `tar -C $mountpoint -cf - --lots-of-options .' (note
+#                the final dot!)  Thus, if you're backing up `/usr' with a
+#                diskfile entry like ``host /usr gnutar-root', but you don't
+#                want to backup /usr/tmp, your exclude list should contain
+#                the pattern `./tmp', as this is relative to the `/usr' above.
+#                Please refer to the man-page of gnutar for more information.
+#                If a relative pathname is specified as the exclude list,
+#                it is searched from within the directory that is
+#                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]
+#   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]
+#   kencrypt   - encrypt the data stream between the client and server.
+#                Default: [kencrypt no]
+#   maxdumps   - max number of concurrent dumps to run on the client.
+#                Default: [maxdumps 1]
+#   priority   - priority level of the dump.  Valid levels are "low", "medium"
+#                or "high".  These are really only used when Amanda has no
+#                tape to write to because of some error.  In that "degraded
+#                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"].
+#   record     - record the dump in /etc/dumpdates.  Default: [record yes]
+#   skip-full  - skip the disk when a level 0 is due, to allow full backups
+#                outside Amanda, eg when the machine is in single-user mode.
+#   skip-incr  - skip the disk when the level 0 is NOT due.  This is used in
+#                archive configurations, where only full dumps are done and
+#                the tapes saved.
+#   starttime  - delay the start of the dump?  Default: no delay
+#   strategy   - set the dump strategy.  Valid strategies are currently:
+#                "standard" - the standard one.
+#                "nofull"   - do level 1 dumps every time.  This can be used,
+#                             for example, for small root filesystems that
+#                             only change slightly relative to a site-wide
+#                             prototype.  Amanda then backs up just the
+#                             changes.
+#                "noinc"    - do level 0 dumps every time.
+#                             Unfortunately, this is not currently
+#                             implemented.  Use `dumpcycle 0'
+#                             instead.
+#                "skip"     - skip all dumps.  Useful for sharing a single
+#                             disklist in several configurations.
+#                "incronly" - do only incremental dumps. This is similar
+#                              to strategy 'nofull', but will increase
+#                              the dump level as usual. Full dumps will
+#                              only be performed when an 'amadmin force' 
+#                              has been issued 
+#                Default: [strategy standard]
+#
+# Note that you may specify previously defined dumptypes as a shorthand way
+# of defining parameters.
+
+define dumptype global {
+    comment "Global definitions"
+    # This is quite useful for setting global parameters, so you don't have
+    # to type them everywhere.  All dumptype definitions in this sample file
+    # do include these definitions, either directly or indirectly.
+    # There's nothing special about the name `global'; if you create any
+    # dumptype that does not contain the word `global' or the name of any
+    # other dumptype that contains it, these definitions won't apply.
+    # Note that these definitions may be overridden in other
+    # dumptypes, if the redefinitions appear *after* the `global'
+    # dumptype name.
+    # You may want to use this for globally enabling or disabling
+    # indexing, recording, etc.  Some examples:
+    # index yes
+    # record no
+}
+
+define dumptype always-full {
+    global
+    comment "Full dump of this filesystem always"
+    compress none
+    priority high
+    dumpcycle 0
+}
+
+define dumptype root-tar {
+    global
+    program "GNUTAR"
+    comment "root partitions dumped with tar"
+    compress none
+    index
+    exclude list "/usr/local/lib/amanda/exclude.gtar"
+    priority low
+}
+
+define dumptype user-tar {
+    root-tar
+    comment "user partitions dumped with tar"
+    priority medium
+}
+
+define dumptype high-tar {
+    root-tar
+    comment "partitions dumped with tar"
+    priority high
+}
+
+define dumptype comp-root-tar {
+    root-tar
+    comment "Root partitions with compression"
+    compress client fast
+}
+
+define dumptype comp-user-tar {
+    user-tar
+    compress client fast
+}
+
+define dumptype holding-disk {
+    global
+    comment "The master-host holding disk itself"
+    holdingdisk no # do not use the holding disk
+    priority medium
+}
+
+define dumptype comp-user {
+    global
+    comment "Non-root partitions on reasonably fast machines"
+    compress client fast
+    priority medium
+}
+
+define dumptype nocomp-user {
+    comp-user
+    comment "Non-root partitions on slow machines"
+    compress none
+}
+
+define dumptype comp-root {
+    global
+    comment "Root partitions with compression"
+    compress client fast
+    priority low
+}
+
+define dumptype nocomp-root {
+    comp-root
+    comment "Root partitions without compression"
+    compress none
+}
+
+define dumptype comp-high {
+    global
+    comment "very important partitions on fast machines"
+    compress client best
+    priority high
+}
+
+define dumptype nocomp-high {
+    comp-high
+    comment "very important partitions on slow machines"
+    compress none
+}
+
+define dumptype nocomp-test {
+    global
+    comment "test dump without compression, no /etc/dumpdates recording"
+    compress none
+    record no
+    priority medium
+}
+
+define dumptype comp-test {
+    nocomp-test
+    comment "test dump with compression, no /etc/dumpdates recording"
+    compress client fast
+}
+
+# network interfaces
+#
+# These are referred to by the disklist file.  They define the attributes
+# of the network interface that the remote machine is accessed through.
+# Notes: - netusage above defines the attributes that are used when the
+#          disklist entry doesn't specify otherwise.
+#        - the values below are only samples.
+#        - specifying an interface does not force the traffic to pass
+#          through that interface.  Your OS routing tables do that.  This
+#          is just a mechanism to stop Amanda trashing your network.
+# Attributes are:
+#      use             - bandwidth above which amanda won't start
+#                        backups using this interface.  Note that if
+#                        a single backup will take more than that,
+#                        amanda won't try to make it run slower!
+
+define interface local {
+    comment "a local disk"
+    use 1000 kbps
+}
+
+define interface le0 {
+    comment "10 Mbps ethernet"
+    use 400 kbps
+}
+
+# You may include other amanda configuration files, so you can share
+# dumptypes, tapetypes and interface definitions among several
+# configurations.
+
+#includefile "/usr/local/amanda.conf.main"
diff --git a/example/amanda.conf.in b/example/amanda.conf.in
new file mode 100644 (file)
index 0000000..01948fb
--- /dev/null
@@ -0,0 +1,560 @@
+###  !!! 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.  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
+dumpuser "@CLIENT_LOGIN@"      # the user to run dumps under
+
+inparallel 4           # maximum dumpers that will run in parallel (max 63)
+                       # this maximum can be increased at compile-time,
+                       # modifying MAX_DUMPERS in server-src/driverio.h
+dumporder "sssS"       # specify the priority order of each dumper
+                       #   s -> smallest size
+                       #   S -> biggest size
+                       #   t -> smallest time
+                       #   T -> biggest time
+                       #   b -> smallest bandwitdh
+                       #   B -> biggest bandwitdh
+                       # try "BTBTBTBTBTBT" if you are not holding
+                       # disk constrained
+netusage  600 Kbps     # maximum net bandwidth for Amanda, in KB per sec
+
+dumpcycle 4 weeks      # the number of days in the normal dump cycle
+runspercycle 20         # the number of amdump runs in dumpcycle days
+                       # (4 weeks * 5 amdump runs per week -- just weekdays)
+tapecycle 25 tapes     # the number of tapes in rotation
+                       # 4 weeks (dumpcycle) times 5 tapes per week (just
+                       # the weekdays) plus a few to handle errors that
+                       # need amflush and so we do not overwrite the full
+                       # backups performed at the beginning of the previous
+                       # cycle
+### ### ###
+# WARNING: don't use `inf' for tapecycle, it's broken!
+### ### ###
+
+bumpsize 20 Mb         # minimum savings (threshold) to bump level 1 -> 2
+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).
+
+
+# Specify tape device and/or tape changer.  If you don't have a tape
+# changer, and you don't want to use more than one tape per run of
+# amdump, just comment out the definition of tpchanger.
+
+# Some tape changers require tapedev to be defined; others will use
+# their own tape device selection mechanism.  Some use a separate tape
+# changer device (changerdev), others will simply ignore this
+# 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.
+
+# 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
+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 "/usr/adm/amanda/@DEFAULT_CONFIG@/changer"
+changerfile "/usr/adm/amanda/@DEFAULT_CONFIG@/changer-status"
+changerfile "@CONFIG_DIR@/@DEFAULT_CONFIG@/changer.conf"
+changerdev "@DEFAULT_CHANGER_DEVICE@"
+
+maxdumpsize -1         # Maximum number of bytes the planner will schedule
+                       # for a run (default: runtapes * tape_length).
+tapetype HP-DAT                # what kind of tape it is (see tapetypes below)
+labelstr "^@DEFAULT_CONFIG@[0-9][0-9]*$"       # label constraint regex: all tapes must match
+
+amrecover_do_fsf yes           # amrecover will call amrestore with the
+                               # -f flag for faster positioning of the tape.
+amrecover_check_label yes      # amrecover will call amrestore with the
+                               # -l flag to check the label.
+amrecover_changer "@DEFAULT_TAPE_DEVICE@"      # amrecover will use the changer if you restore
+                               # from this device.
+                               # It could be a string like 'changer' and
+                               # amrecover will use your changer if you
+                               # set your tape with 'settape changer'
+
+# Specify holding disks.  These are used as a temporary staging area for
+# dumps before they are written to tape and are recommended for most sites.
+# The advantages include: tape drive is more likely to operate in streaming
+# mode (which reduces tape and drive wear, reduces total dump time); multiple
+# dumps can be done in parallel (which can dramatically reduce total dump time.
+# The main disadvantage is that dumps on the holding disk need to be flushed
+# (with amflush) to tape after an operating system crash or a tape failure.
+# If no holding disks are specified then all dumps will be written directly
+# to tape.  If a dump is too big to fit on the holding disk than it will be
+# written directly to tape.  If more than one holding disk is specified then
+# they will all be used based on activity and available space.
+
+holdingdisk hd1 {
+    comment "main holding disk"
+    directory "/dumps/amanda"  # where the holding disk is
+    use 290 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
+                       #             The maximum value should be
+                       #             (MAX_FILE_SIZE - 1Mb)
+                       #  0          same as INT_MAX bytes
+    }
+#holdingdisk hd2 {
+#    directory "/dumps2/amanda"
+#    use 1000 Mb
+#    }
+#holdingdisk hd3 {
+#    directory "/mnt/disk4"
+#    use 1000 Mb
+#    }
+
+
+# If amanda cannot find a tape on which to store backups, it will run
+# as many backups as it can to the holding disks.  In order to save
+# space for unattended backups, by default, amanda will only perform
+# incremental backups in this case, i.e., it will reserve 100% of the
+# holding disk space for the so-called degraded mode backups.
+# However, if you specify a different value for the `reserve'
+# parameter, amanda will not degrade backups if they will fit in the
+# non-reserved portion of the holding disk.
+
+# reserve 30 # percent
+# This means save at least 30% of the holding disk space for degraded
+# mode backups.  
+
+autoflush no #
+# if autoflush is set to yes, then amdump will schedule all dump on
+# holding disks to be flush to tape during the run.
+
+# The format for a ColumnSpec is a ',' seperated list of triples.
+# Each triple consists of
+#   + the name of the column (as in ColumnNameStrings)
+#   + prefix before the column
+#   + the width of the column, if set to -1 it will be recalculated
+#     to the maximum length of a line to print.
+# Example:
+#      "Disk=1:17,HostName=1:10,OutKB=1:7"
+# or
+#      "Disk=1:-1,HostName=1:10,OutKB=1:7"
+#        
+# You need only specify those colums that should be changed from
+# the default. If nothing is specified in the configfile, the
+# above compiled in values will be in effect, resulting in an
+# output as it was all the time.
+# The names of the colums are:
+# HostName, Disk, Level, OrigKB, OutKB, Compress, DumpTime, DumpRate,
+# TapeTime and TapeRate.
+#                                                      ElB, 1999-02-24.
+# columnspec "Disk=1:18,HostName=0:10,OutKB=1:7"
+
+
+# Amanda needs a few Mb of diskspace for the log and debug files,
+# as well as a database.  This stuff can grow large, so the conf directory
+# isn't usually appropriate.  Some sites use /usr/local/var and some /usr/adm.
+# Create an amanda directory under there.  You need a separate infofile and
+# logdir for each configuration, so create subdirectories for each conf and
+# put the files there.  Specify the locations below.
+
+# Note that, although the keyword below is infofile, it is only so for
+# historic reasons, since now it is supposed to be a directory (unless
+# you have selected some database format other than the `text' default)
+infofile "/usr/adm/amanda/@DEFAULT_CONFIG@/curinfo"    # database DIRECTORY
+logdir   "/usr/adm/amanda/@DEFAULT_CONFIG@"            # log directory
+indexdir "/usr/adm/amanda/@DEFAULT_CONFIG@/index"      # index directory
+#tapelist "/usr/adm/amanda/@DEFAULT_CONFIG@/tapelist"  # list of used tapes
+# tapelist is stored, by default, in the directory that contains amanda.conf
+
+
+# tapetypes
+
+# Define the type of tape you use here, and use it in "tapetype"
+# above.  Some typical types of tapes are included here.  The tapetype
+# tells amanda how many MB will fit on the tape, how big the filemarks
+# are, and how fast the tape device is.
+
+# A filemark is the amount of wasted space every time a tape section
+# ends.  If you run `make tapetype' in tape-src, you'll get a program
+# that generates tapetype entries, but it is slow as hell, use it only
+# if you really must and, if you do, make sure you post the data to
+# the amanda mailing list, so that others can use what you found out
+# by searching the archives.
+
+# For completeness Amanda should calculate the inter-record gaps too,
+# but it doesn't.  For EXABYTE and DAT tapes this is ok.  Anyone using
+# 9 tracks for amanda and need IRG calculations?  Drop me a note if
+# so.
+
+# If you want amanda to print postscript paper tape labels
+# add a line after the comment in the tapetype of the form
+#    lbl-templ "/path/to/postscript/template/label.ps"
+
+# if you want the label to go to a printer other than the default
+# for your system, you can also add a line above for a different
+# printer. (i usually add that line after the dumpuser specification)
+
+# dumpuser "operator"     # the user to run dumps under
+# printer "mypostscript"  # printer to print paper label on
+
+# here is an example of my definition for an EXB-8500
+
+# define tapetype EXB-8500 {
+# ...
+#     lbl-templ "/usr/local/amanda/config/lbl.exabyte.ps"
+# }
+
+
+define tapetype QIC-60 {
+    comment "Archive Viper"
+    length 60 mbytes
+    filemark 100 kbytes                # don't know a better value
+    speed 100 kbytes           # dito
+}
+
+define tapetype DEC-DLT2000 {
+    comment "DEC Differential Digital Linear Tape 2000"
+    length 15000 mbytes
+    filemark 8 kbytes
+    speed 1250 kbytes
+}
+
+# goluboff@butch.Colorado.EDU
+# in amanda-users (Thu Dec 26 01:55:38 MEZ 1996)
+define tapetype DLT {
+    comment "DLT tape drives"
+    length 20000 mbytes                # 20 Gig tapes
+    filemark 2000 kbytes       # I don't know what this means
+    speed 1536 kbytes          # 1.5 Mb/s
+}
+
+define tapetype SURESTORE-1200E {
+    comment "HP AutoLoader"
+    length 3900 mbytes
+    filemark 100 kbytes
+    speed 500 kbytes
+}
+
+define tapetype EXB-8500 {
+    comment "Exabyte EXB-8500 drive on decent machine"
+    length 4200 mbytes
+    filemark 48 kbytes
+    speed 474 kbytes                   
+}
+
+define tapetype EXB-8200 {
+    comment "Exabyte EXB-8200 drive on decent machine"
+    length 2200 mbytes
+    filemark 2130 kbytes
+    speed 240 kbytes                   
+}
+
+define tapetype HP-DAT {
+    comment "DAT tape drives"
+    # data provided by Rob Browning <rlb@cs.utexas.edu>
+    length 1930 mbytes
+    filemark 111 kbytes
+    speed 468 kbytes
+}
+
+define tapetype DAT {
+    comment "DAT tape drives"
+    length 1000 mbytes         # these numbers are not accurate
+    filemark 100 kbytes                # but you get the idea
+    speed 100 kbytes
+}
+
+define tapetype MIMSY-MEGATAPE {
+    comment "Megatape (Exabyte based) drive through Emulex on Vax 8600"
+    length 2200 mbytes
+    filemark 2130 kbytes
+    speed 170 kbytes           # limited by the Emulex bus interface, ugh
+}
+
+
+# dumptypes
+#
+# These are referred to by the disklist file.  The dumptype specifies
+# certain parameters for dumping including:
+#   auth       - authentication scheme to use between server and client.
+#                Valid values are "bsd" and "krb4".  Default: [auth bsd]
+#   comment    - just a comment string
+#   comprate   - set default compression rate.  Should be followed by one or
+#                two numbers, optionally separated by a comma.  The 1st is
+#                the full compression rate; the 2nd is the incremental rate.
+#                If the second is omitted, it is assumed equal to the first.
+#                The numbers represent the amount of the original file the
+#                compressed file is expected to take up.
+#                Default: [comprate 0.50, 0.50]
+#   compress   - specify compression of the backed up data.  Valid values are:
+#                "none"        - don't compress the dump output.
+#                "client best" - compress on the client using the best (and
+#                                probably slowest) algorithm.
+#                "client fast" - compress on the client using fast algorithm.
+#                "server best" - compress on the tape host using the best (and
+#                                probably slowest) algorithm.
+#                "server fast" - compress on the tape host using a fast
+#                                algorithm.  This may be useful when a fast
+#                                tape host is backing up slow clients.
+#                Default: [compress client fast]
+#   dumpcycle  - set the number of days in the dump cycle, ie, set how often a
+#                full dump should be performed.  Default: from DUMPCYCLE above
+#   exclude    - specify files and directories to be excluded from the dump.
+#                Useful with gnutar only; silently ignored by dump and samba.
+#                Valid values are:
+#                "pattern"       - a shell glob pattern defining which files
+#                                  to exclude.
+#                                  gnutar gets --exclude="pattern"
+#                list "filename" - a file (on the client!) containing patterns
+#                                  re's (1 per line) defining which files to
+#                                  exclude.
+#                                  gnutar gets --exclude-from="filename"
+#                Note that the `full pathname' of a file within its
+#                filesystem starts with `./', because of the way amanda runs
+#                gnutar: `tar -C $mountpoint -cf - --lots-of-options .' (note
+#                the final dot!)  Thus, if you're backing up `/usr' with a
+#                diskfile entry like ``host /usr gnutar-root', but you don't
+#                want to backup /usr/tmp, your exclude list should contain
+#                the pattern `./tmp', as this is relative to the `/usr' above.
+#                Please refer to the man-page of gnutar for more information.
+#                If a relative pathname is specified as the exclude list,
+#                it is searched from within the directory that is
+#                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]
+#   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]
+#   kencrypt   - encrypt the data stream between the client and server.
+#                Default: [kencrypt no]
+#   maxdumps   - max number of concurrent dumps to run on the client.
+#                Default: [maxdumps 1]
+#   maxpromoteday - max number of day for a promotion, set it 0 if you don't
+#                want promotion, set it to 1 or 2 if your disk get
+#                overpromoted.
+#                Default: [10000]
+#   priority   - priority level of the dump.  Valid levels are "low", "medium"
+#                or "high".  These are really only used when Amanda has no
+#                tape to write to because of some error.  In that "degraded
+#                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"].
+#   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.).
+#                Default: [record yes]
+#   skip-full  - skip the disk when a level 0 is due, to allow full backups
+#                outside Amanda, eg when the machine is in single-user mode.
+#   skip-incr  - skip the disk when the level 0 is NOT due.  This is used in
+#                archive configurations, where only full dumps are done and
+#                the tapes saved.
+#   starttime  - delay the start of the dump?  Default: no delay
+#   strategy   - set the dump strategy.  Valid strategies are currently:
+#                "standard" - the standard one.
+#                "nofull"   - do level 1 dumps every time.  This can be used,
+#                             for example, for small root filesystems that
+#                             only change slightly relative to a site-wide
+#                             prototype.  Amanda then backs up just the
+#                             changes.
+#                "noinc"    - do level 0 dumps every time.
+#                             Unfortunately, this is not currently
+#                             implemented.  Use `dumpcycle 0'
+#                             instead.
+#                "skip"     - skip all dumps.  Useful for sharing a single
+#                             disklist in several configurations.
+#                "incronly" - do only incremental dumps. This is similar
+#                              to strategy 'nofull', but will increase
+#                              the dump level as usual. Full dumps will
+#                              only be performed when an 'amadmin force' 
+#                              has been issued 
+#                Default: [strategy standard]
+#
+# Note that you may specify previously defined dumptypes as a shorthand way
+# of defining parameters.
+
+define dumptype global {
+    comment "Global definitions"
+    # This is quite useful for setting global parameters, so you don't have
+    # to type them everywhere.  All dumptype definitions in this sample file
+    # do include these definitions, either directly or indirectly.
+    # There's nothing special about the name `global'; if you create any
+    # dumptype that does not contain the word `global' or the name of any
+    # other dumptype that contains it, these definitions won't apply.
+    # Note that these definitions may be overridden in other
+    # dumptypes, if the redefinitions appear *after* the `global'
+    # dumptype name.
+    # You may want to use this for globally enabling or disabling
+    # indexing, recording, etc.  Some examples:
+    # index yes
+    # record no
+}
+
+define dumptype always-full {
+    global
+    comment "Full dump of this filesystem always"
+    compress none
+    priority high
+    dumpcycle 0
+}
+
+define dumptype root-tar {
+    global
+    program "GNUTAR"
+    comment "root partitions dumped with tar"
+    compress none
+    index
+    exclude list "/usr/local/lib/amanda/exclude.gtar"
+    priority low
+}
+
+define dumptype user-tar {
+    root-tar
+    comment "user partitions dumped with tar"
+    priority medium
+}
+
+define dumptype high-tar {
+    root-tar
+    comment "partitions dumped with tar"
+    priority high
+}
+
+define dumptype comp-root-tar {
+    root-tar
+    comment "Root partitions with compression"
+    compress client fast
+}
+
+define dumptype comp-user-tar {
+    user-tar
+    compress client fast
+}
+
+define dumptype holding-disk {
+    global
+    comment "The master-host holding disk itself"
+    holdingdisk no # do not use the holding disk
+    priority medium
+}
+
+define dumptype comp-user {
+    global
+    comment "Non-root partitions on reasonably fast machines"
+    compress client fast
+    priority medium
+}
+
+define dumptype nocomp-user {
+    comp-user
+    comment "Non-root partitions on slow machines"
+    compress none
+}
+
+define dumptype comp-root {
+    global
+    comment "Root partitions with compression"
+    compress client fast
+    priority low
+}
+
+define dumptype nocomp-root {
+    comp-root
+    comment "Root partitions without compression"
+    compress none
+}
+
+define dumptype comp-high {
+    global
+    comment "very important partitions on fast machines"
+    compress client best
+    priority high
+}
+
+define dumptype nocomp-high {
+    comp-high
+    comment "very important partitions on slow machines"
+    compress none
+}
+
+define dumptype nocomp-test {
+    global
+    comment "test dump without compression, no /etc/dumpdates recording"
+    compress none
+    record no
+    priority medium
+}
+
+define dumptype comp-test {
+    nocomp-test
+    comment "test dump with compression, no /etc/dumpdates recording"
+    compress client fast
+}
+
+# network interfaces
+#
+# These are referred to by the disklist file.  They define the attributes
+# of the network interface that the remote machine is accessed through.
+# Notes: - netusage above defines the attributes that are used when the
+#          disklist entry doesn't specify otherwise.
+#        - the values below are only samples.
+#        - specifying an interface does not force the traffic to pass
+#          through that interface.  Your OS routing tables do that.  This
+#          is just a mechanism to stop Amanda trashing your network.
+# Attributes are:
+#      use             - bandwidth above which amanda won't start
+#                        backups using this interface.  Note that if
+#                        a single backup will take more than that,
+#                        amanda won't try to make it run slower!
+
+define interface local {
+    comment "a local disk"
+    use 1000 kbps
+}
+
+define interface le0 {
+    comment "10 Mbps ethernet"
+    use 400 kbps
+}
+
+# You may include other amanda configuration files, so you can share
+# dumptypes, tapetypes and interface definitions among several
+# configurations.
+
+#includefile "/usr/local/amanda.conf.main"
diff --git a/example/chg-mcutil.conf b/example/chg-mcutil.conf
new file mode 100644 (file)
index 0000000..95df670
--- /dev/null
@@ -0,0 +1,66 @@
+# config file for the chg-mcutil tape changer program.
+# Used when tpchanger "chg-mcutil" is specified in amanda.conf.
+
+# chg-mcutil is mainly designed for use with Compaq TRU64.
+# chg-mcutil uses a binary program called `mcutil`, a Media
+# changer manipulation utility.  mcutil comes installed with
+# TRU64 5.0x & above.  However, with TRU64 4.0x, it can be
+# located on one of the Associated Product CDs.
+
+# A few OS commands that this script relies on to function
+# correctly.  Please make sure they exist, and are in the 
+# $PATH:
+#
+# date, cut, tr, cat, expr, grep, awk
+#
+
+# Before you can use chg-mcutil within amanda, you need
+# to make sure that `mcutil` can see, and interact with your
+# tape changer.  You need to be able to successfully run the
+# following:
+#
+# mcutil -e drive
+# mcutil -e slot
+# mcutil -m drive slot:#
+# mcutil -m slot:# drive
+#
+
+mcutil mcutil          #location of the mcutil program
+tape /dev/null # use ntape for norewind
+                       # {a|m|h|c} suffixes should NOT 
+                       # be tape device since they all
+                       # implement hardware compression
+
+# What are the slot numbers of the tape changer as reported by mcutil?
+firstslot 0
+lastslot 6
+
+# Do you want amanda to determine when you should clean the tape drive?
+use_cleaning 0         # 0 for yes ; 1 for no
+cleanslot 7            # slot containing the cleaning disk
+cleansleep 300         # How long to wait before the cleaning tape finishes (default: 5 min)
+cleanme 45             # number of days before messages popup to clean tape drive
+cleanfile /u/martinea/etc/amanda/changer/times_cleaned
+lastfile /u/martinea/etc/amanda/changer/last_cleaned
+
+# Names a status file where the current 'changer' state is stored.
+currentslot /u/martinea/etc/amanda/changer/currentslot
+
+# Where to log changer debugging info
+logfile /tmp/amanda/changer.debug
+
+
+# To determine what slot is currently used, I query the drive itself.
+# /sbin/mcutil -e drive
+# With a Tape : drive 0 [full,access,source=256]  16
+# Without Tape: drive 0 [empty,access]  16
+#
+# each slot has a source number assigned to it.  I subtract slot 0's source num from the output.
+# If the number is less than 0, no tape is in the drive, else it outputs the current slot number.
+#
+# slot 0 [full,access,source=256] 256
+# slot 1 [full,access,source=257] 257
+# slot 2 [full,access,source=258] 258
+# slot 3 [full,access,source=259] 259
+#
+slot0source 256                # run /sbin/mcutil -e slot to determine slot0 source number.
diff --git a/example/chg-mcutil.conf.in b/example/chg-mcutil.conf.in
new file mode 100644 (file)
index 0000000..e6dfe3a
--- /dev/null
@@ -0,0 +1,66 @@
+# config file for the chg-mcutil tape changer program.
+# Used when tpchanger "chg-mcutil" is specified in amanda.conf.
+
+# chg-mcutil is mainly designed for use with Compaq TRU64.
+# chg-mcutil uses a binary program called `mcutil`, a Media
+# changer manipulation utility.  mcutil comes installed with
+# TRU64 5.0x & above.  However, with TRU64 4.0x, it can be
+# located on one of the Associated Product CDs.
+
+# A few OS commands that this script relies on to function
+# correctly.  Please make sure they exist, and are in the 
+# $PATH:
+#
+# date, cut, tr, cat, expr, grep, awk
+#
+
+# Before you can use chg-mcutil within amanda, you need
+# to make sure that `mcutil` can see, and interact with your
+# tape changer.  You need to be able to successfully run the
+# following:
+#
+# mcutil -e drive
+# mcutil -e slot
+# mcutil -m drive slot:#
+# mcutil -m slot:# drive
+#
+
+mcutil @MCUTIL@                #location of the mcutil program
+tape @DEFAULT_TAPE_DEVICE@     # use ntape for norewind
+                       # {a|m|h|c} suffixes should NOT 
+                       # be tape device since they all
+                       # implement hardware compression
+
+# What are the slot numbers of the tape changer as reported by mcutil?
+firstslot 0
+lastslot 6
+
+# Do you want amanda to determine when you should clean the tape drive?
+use_cleaning 0         # 0 for yes ; 1 for no
+cleanslot 7            # slot containing the cleaning disk
+cleansleep 300         # How long to wait before the cleaning tape finishes (default: 5 min)
+cleanme 45             # number of days before messages popup to clean tape drive
+cleanfile @CONFIG_DIR@/changer/times_cleaned
+lastfile @CONFIG_DIR@/changer/last_cleaned
+
+# Names a status file where the current 'changer' state is stored.
+currentslot @CONFIG_DIR@/changer/currentslot
+
+# Where to log changer debugging info
+logfile @AMANDA_DBGDIR@/changer.debug
+
+
+# To determine what slot is currently used, I query the drive itself.
+# /sbin/mcutil -e drive
+# With a Tape : drive 0 [full,access,source=256]  16
+# Without Tape: drive 0 [empty,access]  16
+#
+# each slot has a source number assigned to it.  I subtract slot 0's source num from the output.
+# If the number is less than 0, no tape is in the drive, else it outputs the current slot number.
+#
+# slot 0 [full,access,source=256] 256
+# slot 1 [full,access,source=257] 257
+# slot 2 [full,access,source=258] 258
+# slot 3 [full,access,source=259] 259
+#
+slot0source 256                # run /sbin/mcutil -e slot to determine slot0 source number.
diff --git a/example/chg-multi.conf b/example/chg-multi.conf
new file mode 100644 (file)
index 0000000..0d12e57
--- /dev/null
@@ -0,0 +1,65 @@
+# config file for the chg-multi tape changer program.
+# Used when tpchanger "chg-multi" is specified in amanda.conf.
+
+# chg-multi supports several configurations, with or without an actual 
+# changer. Please see docs/TAPE.CHANGERS for a description
+#
+# chg-multi should actually work directly with any changer that allows
+# access to the slots via Unix devices that look to software like
+# regular tape drives. (that is, you don't need a changer driver...).
+
+# Configuration variables:
+#  
+#  'multieject': use an 'mt offline' command to change to the next
+#    tape, or multiple such commands for skipping several tapes at a
+#    time. 
+#
+#  'needeject': this option is incompatible with 'multieject'. This is 
+#    needed for changers accessed through several virtual tape
+#    devices, when the changer needs the current tape to be ejected
+#    before changing to another device.
+#
+#  'gravity': set this to 1 if the changer/stacker is unable to loop
+#    back to the first tape after unloading the last one, or if you
+#    don't want amanda to go through the tape stack looking for the
+#    exact tape it wants instead of using the first acceptable one.
+#
+#  slot X: The configuration file should list as many 'slot X'
+#    statements as the number of slots supported by the changer or the 
+#    number of separate tape drives used.
+
+# For changers that need an 'mt offline' to load the next tape
+multieject 0
+
+# Is this a gravity stacker that can't go backwards or cycle ?  If
+# yes, set gravity to 1.
+gravity 0
+
+# Does this tape-changer need an explicit eject command before loading
+# a new tape?  If you are using multiple drives as a tape changer, you
+# don't want to do this, but if you are using an auto-changer that
+# allows access to the slots through Unix tape devices, it might block
+# the mount of a new slot until the old is explicitly ejected.  In
+# that case, set needeject to 1.
+needeject 0
+
+# On some machines there is a delay between when the eject command
+# finishes and the next tape is ready to be accessed.  Set ejectdelay
+# to the number of seconds to wait after an eject command. This will
+# almost certainly be needed if multieject is set, probably not if
+# needeject is used.
+ejectdelay 0
+
+# Names a status file where the current ``changer'' state is stored.
+statefile /usr/adm/amanda/csd/changer-status
+
+# What are the slot numbers used in the tape rack?
+firstslot 1
+lastslot 4
+
+# Enumerate the device files that go with the particular tape changer
+# slots. Don't forget to specify the no-rewind version of the device.
+slot 1 /dev/nrst8
+slot 2 /dev/nrst9
+slot 3 /dev/nrst10
+slot 4 /dev/nrst11
diff --git a/example/chg-scsi-hpux.conf.in b/example/chg-scsi-hpux.conf.in
new file mode 100644 (file)
index 0000000..42d7a4d
--- /dev/null
@@ -0,0 +1,19 @@
+number_configs 1
+eject          0       # Tapedrives need an eject command
+sleep          90      # Seconds to wait until the tape gets ready
+cleanmax       100     # How many times could a cleaning tape get used
+changerdev     /dev/scsi/4:1
+#
+# Next comes the data for drive 0
+#
+config         0
+drivenum       0
+dev            /dev/rmt/0mnb
+startuse       0       # The slots associated with the drive 0
+enduse         4       # 
+statfile       @CONFIG_DIR@/@DEFAULT_CONFIG@/tape0-slot  # The file where the actual slot is stored
+cleancart      5       # the slot where the cleaningcartridge for drive 0 is located
+cleanfile      @CONFIG_DIR@/@DEFAULT_CONFIG@/tape0-clean # The file where the cleanings are recorded
+usagecount     @CONFIG_DIR@/@DEFAULT_CONFIG@/totaltime
+tapestatus     @CONFIG_DIR@/@DEFAULT_CONFIG@/tapestatus
+#labelfile     @CONFIG_DIR@/@DEFAULT_CONFIG@/labelfile # Use this if you have an barcode reader
diff --git a/example/chg-scsi-linux.conf.in b/example/chg-scsi-linux.conf.in
new file mode 100644 (file)
index 0000000..8fbd388
--- /dev/null
@@ -0,0 +1,20 @@
+number_configs 1
+eject          0       # Tapedrives need an eject command
+sleep          90      # Seconds to wait until the tape gets ready
+cleanmax       100     # How many times could a cleaning tape get used
+changerdev     /dev/sg2
+#
+# Next comes the data for drive 0
+#
+config         0
+drivenum       0
+dev            /dev/nst0
+scsitapedev    /dev/sg1
+startuse       0       # The slots associated with the drive 0
+enduse         4       # 
+statfile       @CONFIG_DIR@/@DEFAULT_CONFIG@/tape0-slot  # The file where the actual slot is stored
+cleancart      5       # the slot where the cleaningcartridge for drive 0 is located
+cleanfile      @CONFIG_DIR@/@DEFAULT_CONFIG@/tape0-clean # The file where the cleanings are recorded
+usagecount     @CONFIG_DIR@/@DEFAULT_CONFIG@/totaltime
+tapestatus     @CONFIG_DIR@/@DEFAULT_CONFIG@/tapestatus # here will some status infos be stored
+#labelfile     @CONFIG_DIR@/@DEFAULT_CONFIG@/labelfile # Use this if you have an barcode reader
diff --git a/example/chg-scsi-solaris.conf.in b/example/chg-scsi-solaris.conf.in
new file mode 100644 (file)
index 0000000..d74e68b
--- /dev/null
@@ -0,0 +1,19 @@
+number_configs 1
+eject          0       # Tapedrives need an eject command
+sleep          60      # Seconds to wait until the tape gets ready
+cleanmax       10      # How many times could a cleaning tape get used
+changerdev     /dev/rsst4
+#
+# Next comes the data for drive 0
+#
+config         0
+drivenum       0
+dev            /dev/rmt/0bn    # the device that is used for the tapedrive 0 (BSD type, no rewind, no compression)
+startuse       0       # The slots associated with the drive 0
+enduse         4       # 
+statfile       @CONFIG_DIR@/@DEFAULT_CONFIG@/tape0-slot  # The file where the actual slot is stored
+cleancart      5       # the slot where the cleaningcartridge for drive 0 is located
+cleanfile      @CONFIG_DIR@/@DEFAULT_CONFIG@/tape0-clean # The file where the cleanings are recorded
+usagecount     @CONFIG_DIR@/@DEFAULT_CONFIG@/totaltime
+tapestatus      @CONFIG_DIR@/@DEFAULT_CONFIG@/tape0-status
+#labelfile     @CONFIG_DIR@/@DEFAULT_CONFIG@/labelfile # Use this if you have an barcode reader
diff --git a/example/chg-scsi.conf b/example/chg-scsi.conf
new file mode 100644 (file)
index 0000000..866ceb2
--- /dev/null
@@ -0,0 +1,32 @@
+
+number_configs 2
+eject          1       # Tapedrives need an eject command
+sleep          5       # Seconds to wait until the tape gets ready
+cleanmax       10      # How many times could a cleaning tape get used
+changerdev     /dev/sch0
+#
+# Next comes the data for drive 0
+#
+config         0
+drivenum       0
+dev            /dev/tape0      # the device that is used for the tapedrive 0
+startuse       0       # The slots associated with the drive 0
+enduse         9       # 
+statfile       /usr/local/etc/amanda/tape5-slot  # The file where the actual slot is stored
+cleancart      20      # the slot where the cleaningcartridge for drive 0 is located
+cleanfile      /usr/local/etc/amanda/tape0-clean # The file where the cleanings are recorded
+usagecount     /usr/local/etc/amanda/backup/totaltime
+
+# Next comes the data for drive 1
+
+config         1
+drivenum       1
+dev            /dev/tape1      # the device that is used for the tapedrive 0
+startuse       10      # The slots associated with the drive 0
+enduse         19      # 
+statfile       /usr/local/etc/amanda/tape1-slot  # The file where the actual slot is stored
+cleancart      21      # the slot where the cleaningcartridge for drive 0 is located
+cleanfile      /usr/local/etc/amanda/tape1-clean # The file where the cleanings are recorded
+usagecount     /usr/local/etc/amanda/backup1/totaltime
+#
+# This is the end
diff --git a/example/config.site b/example/config.site
new file mode 100644 (file)
index 0000000..2bbd0c9
--- /dev/null
@@ -0,0 +1,442 @@
+######################################################################
+#
+# Site dependend configuration.  Please edit this file for your
+# local site and place it in $prefix/share or $prefix/etc.
+#
+# For those options that need to replace the default configuration,
+# remove the beginning # at beginning of the line and set the
+# options to how you like it.
+#
+# These options can also be set on the command line for the configure
+# script.  The appropriate option for the option is listed along with
+# the option.
+#
+######################################################################
+
+# These are the directories for the Amanda programs and files.
+#
+# Let $prefix be the location of the root Amanda directory, commonly
+# /usr/local or /opt/amanda.  $prefix is set by using configure --prefix=.
+# Other directories are setable:
+#    $prefix           --prefix=               Default:/usr/local
+#    $exec_prefix      --exec-prefix=          Default:$prefix
+#    $sbindir          --sbindir=              Default:$exec_prefix/sbin
+#    $libexecdir       --libexecdir=           Default:$exec_prefix/libexec
+#    $libdir           --libdir=               Default:$exec_prefix/lib
+#    $sysconfdir       --sysconfdir=           Default:$prefix/etc
+#    $localstatedir    --localstatedir=        Default:$prefix/var
+#    $mandir           --mandir=               Default:$prefix/man
+
+# sbindir              --sbindir=DIR
+#                      Default: $exec_prefix/sbin = /usr/local/sbin
+#                      Directory containing the server side binaries.
+# sbindir=/usr/local/sbin
+
+
+# libexecdir           --libexecdir=DIR
+#                      Default: $exec_prefix/libexec = /usr/local/libexec
+#                      Directory containing the client side binaries.
+# libexecdir=/usr/local/lib/amanda
+
+
+# lib                  --libdir=DIR
+#                      Default: $exec_prefix/lib = /usr/local/lib
+#                      Directory containing the amanda (shared) libraries.
+# libdir=/usr/local/lib/amanda
+
+
+# mandir               --mandir=DIR
+#                      Default: $prefix/man = /usr/local/man
+#                      Directory containing the manual pages.
+# mandir=/local/man
+
+
+# INCLUDE_DIRS         --with-includes="DIR DIR ..."
+#                      Default: empty
+#                      Non-standard directories where include files should
+#                      be looked for.
+# INCLUDE_DIRS="/opt/gnu/readline/include /opt/gnu/gdbm/include"
+
+
+# LIBRARY_DIRS         --with-libraries="DIR DIR ..."
+#                      Default: empty
+#                      Non-standard directories where libraries should
+#                      be looked for.
+# LIBRARY_DIRS="/opt/gnu/readline/lib /opt/gnu/gdbm/lib"
+
+
+# CONFIG_DIR           --with-configdir=DIR
+#                      Default: $sysconfdir/amanda = /usr/local/etc/amanda
+#                      Directory where the runtime files are to be
+#                      found.  Amanda supports multiple
+#                      configurations per site; these are contained
+#                      in subdirectories of CONFIG_DIR.
+# CONFIG_DIR=/usr/local/etc/amanda
+
+
+# USE_VERSION_SUFFIXES --with-suffixes
+#                      Default: no
+#                      All the Amanda binaries will be installed with a
+#                      version string appended to the command name, for
+#                      example "amdump-2.3.0.4".  You must then set up
+#                      symlinks from "amdump" to the correct version of
+#                      the binary, or use them with the version suffixes
+#                      directly.
+#                      This is mostly useful when you want multiple
+#                      versions online for testing purposes.  I recommend
+#                      it if you are doing a major version upgrade and
+#                      wish to try out the new version in parallel with
+#                      the old.
+# USE_VERSION_SUFFIXES=yes
+
+
+# NO_SERVER_MODE       --without-server
+#                      Default: false
+#                      if true, disables building server stuff.
+# NO_SERVER_MODE=true
+
+
+# NO_CLIENT_MODE       --without-client
+#                      Default: false
+#                      if true, disables building client stuff.
+# NO_CLIENT_MODE=true
+
+
+# NO_RESTORE_MODE      --without-restore
+#                      Default: false
+#                      if true, disables building amrestore and amidxtaped
+# NO_RESTORE_MODE=true
+
+
+# NO_RECOVER_MODE      --without-amrecover
+#                      Default: false
+#                      if true, disables building amrecover.
+# NO_RECOVER_MODE=true
+
+
+# DEFAULT_SERVER       --with-index-server=HOST
+#                      Default: name of the machine configure is run on
+#                      The default server for the index of files dumped
+#                      database.
+# DEFAULT_SERVER=kipuka
+
+
+# FORCE_USERID         --with-dont-force-uid
+#                      Default: yes
+#                      FORCE_USERID controls whether or not the Amanda
+#                      client-side should suid to a non-priveledged user
+#                      when inetd runs it as root.  Most older inetds do
+#                      not allow you to specify which user to run a daemon
+#                      as in inetd.conf; all daemons are just run as root.
+#                      We prefer to not do anything as root that can be
+#                      done as a normal user, so unless FORCE_USERID is set
+#                      to no, Amanda will switch to the user specified by
+#                      CLIENT_LOGIN for all further operations on the slave
+#                      host.  This type of operation normally requires that
+#                      the CLIENT_LOGIN be in some group that has read
+#                      permissions on the raw disk devices, and read/write
+#                      permissions on /etc/dumpdates.
+# FORCE_USERID=no
+
+
+# CLIENT_LOGIN         --with-user=USERNAME
+#                      This flag *must* be specified
+#                      The user to install as the owner of all Amanda
+#                      programs and the user to switch to on client
+#                      machines.
+# CLIENT_LOGIN=amanda
+
+
+# SETUID_GROUP         --with-group=GROUPNAME
+#                      This flag *must* be specified
+#                      The name of the group to install all files under.
+# SETUID_GROUP=bin
+
+
+# USE_RUNDUMP          --with-rundump
+#                      Default: no (unless xfsdump or vdump are found)
+#                      Enables the usage of the rundump setuid-root
+#                      program, that invokes dump as root.
+# USE_RUNDUMP=yes
+
+
+# DEFAULT_CONFIG       --with-config=CONFIG
+#                      Default: DailySet1
+#                      The default configuration name of the default
+#                      dump set up.  This gets used throughout the
+#                      configuration of Amanda.
+# DEFAULT_CONFIG=DailySet1
+
+
+# DEFAULT_TAPE_SERVER  --with-tape-server=TAPE_SERVER
+#                      Default: DEFAULT_SERVER or [--with-index-server]
+#                      This is the name of the machine which serves as the
+#                      default machine to recover files from tape using
+#                      amrecover.  The default machine is the one used
+#                      for DEFAULT_SERVER.
+# DEFAULT_TAPE_SERVER=kipuka
+
+
+# DEFAULT_TAPE_DEVICE  --with-tape-device=TAPE_DEVICE
+#                      Default: /dev/rmt/[0-9]bn or /dev/nrst[0-9]
+#                      This sets the default no rewinding tape device.  The
+#                      configure script will search for the lowest numbered
+#                      /dev/rmt/[0-9]bn device and if none exist, it will
+#                      use the lowest numbered /dev/nrst[0-9] device.  If
+#                      no tape device is found, /dev/null is used.
+#
+#                      This is also the name of the no rewinding tape device
+#                      on the the DEFAULT_TAPE_SERVER machine for
+#                      restoring backups.
+# DEFAULT_TAPE_DEVICE=/dev/rmt/0bn
+# DEFAULT_TAPE_DEVICE=/dev/nrst0
+
+
+# DEFAULT_RAW_TAPE_DEVICE  --with-ftape-rawdevice=RAW_TAPE_DEVICE
+#           Default: /dev/rawft[0-3]
+#           This sets the default raw tape device for use with the Linux 
+#           floppy tape driver ftape (version 3.04d).
+#           The configure script will search for the lowest numbered
+#           /dev/rawft[0-3] device. If no device is found, /dev/null is used.
+#
+#           This device is needed for QIC volume table operations with 
+#           floppy tapes.
+# DEFAULT_RAW_TAPE_DEVICE=/dev/rawft0
+
+
+# DEFAULT_CHANGER_DEVICE --with-changer-device=CHANGER_DEVICE
+#                      Default: /dev/ch0 or /dev/null
+#                      This sets the default tape changer device.
+#                      If /dev/ch0 exists, it is used, otherwise, no
+#                      changer device is defined.
+# DEFAULT_CHANGER_DEVICE=/dev/ch0
+
+
+# USE_FQDN             --with-fqdn
+#                      Default: no
+#                      Allow Amanda to backup systems in different
+#                      domains.  This requires that the disklist file
+#                      have the fully qualified domain names (FQDNs)
+#                      listed.
+# USE_FQDN=yes
+
+
+# SAMBA_CLIENT         --with-smbclient=PROG
+#                      Default: no
+#                      Tell Amanda where to find the smbclient program,
+#                      which does the backing up of Samba PC clients.
+#                      Look in the patches/ directory for patches to
+#                      apply to Samba for this to work properly.
+# SAMBA_CLIENT=/usr/local/bin/smbclient
+
+
+# GNUTAR               --with-gnutar=PROG
+#                      Default: look for program named gtar, gnutar or tar
+#                      that prints GNU tar when run with --version.
+# GNUTAR=/usr/local/bin/gnutar
+
+# GNUTAR_LISTDIR       --with-gnutar-listdir[=DIR]
+#                      Default: $localstatedir/amanda/gnutar-lists =
+#                              /usr/local/var/amanda/gnutar-lists
+#                      This specifies the directory where gnutar should
+#                      place the listed incrementals directory lists it 
+#                      uses to do incremental backups.
+# GNUTAR_LISTDIR=/usr/local/var/amanda/gnutar-lists
+
+
+# DEV_PREFIX
+#                      Default: system specific
+#                      Define DEV_PREFIX is the configure script can not
+#                      figure out the correct device prefix for the disk
+#                      devices.
+# DEV_PREFIX="/dev/"
+
+
+# RDEV_PREFIX
+#                      Default: system specific
+#                      Define DEV_PREFIX is the configure script can not
+#                      figure out the correct device prefix for the raw
+#                      disk devices.
+# RDEV_PREFIX="/dev/r"
+
+
+# BSD_SECURITY         --without-bsd-security
+#                      Default: yes
+#                      BSD_SECURITY selects BSD rsh/rlogin style security,
+#                      which is not great, but is in common use, and its
+#                      strengths and weaknesses are well known.  Under
+#                      BSD_SECURITY, the Amanda backup client hosts will
+#                      check .rhosts (or .amandahosts, see below)
+#                      files before sending any dump data.
+# BSD_SECURITY=no
+
+
+# USE_AMANDAHOSTS      --without-amandahosts
+#                      Default: yes
+#                      When BSD_SECURITY is used, by default it will use
+#                      the .amandahosts file to make sure that the remote
+#                      user can tell the Amanda client what to do.  If you
+#                      wish to use the more standard .rhosts and
+#                      /etc/hosts.equiv files instead, then define this to
+#                      no.  Unlike .rhosts, .amandahosts cannot contain
+#                      lines with hostnames only; the username must always
+#                      be specified.
+# USE_AMANDAHOSTS=no
+
+
+# PORTRANGE             --with-portrange=min,max
+#                      Default: unlimited
+#                      Limits the range of ports that TCP server
+#                      sockets will be bound to.  It does not affect
+#                      reserved (<1024) ports, though.  This is useful 
+#                      for backing up hosts behind firewalls: they can
+#                      be configured to use this limited range of
+#                      ports for data, message and index connections.
+# PORTRANGE=50000,50100
+
+
+# UDPPORTRANGE          --with-udpportrange=min,max
+#                      Default: unlimited
+#                      Limits the range of ports that UDP sockets
+#                      will be bound to.  This one *does* affect
+#                      reserved (<1024) ports, except those handed to
+#                      amandad by inetd, of course.  This is useful 
+#                      for backing up hosts behind firewalls: they can
+#                      be configured to use this limited range of
+#                      ports for requests.
+# UDPPORTRANGE=512,520
+
+
+# KRB4_SECURITY                --with-krb4-security
+#                      Default: no
+#                      KRB4_SECURITY selects MIT Kerberos version 4 style
+#                      security, which is significantly better than
+#                      BSD_SECURITY, providing for mutual authentication
+#                      and (optionally) encryption of backup data over the
+#                      network.  Both BSD_SECURITY and KRB4_SECURITY may be
+#                      defined at the same time: the type of security to be
+#                      used can be selected on a per-client-host basis (in
+#                      the disklist file).
+#                      NOTE: Due to stupid USA export restrictions, use of
+#                      KRB4_SECURITY requires source files from the separate
+#                      "amanda-krb4" package.  See the KERBEROS.HOW-TO-GET
+#                      instructions on the Amanda home ftp site,
+#                      ftp.amanda.org.
+# KRB4_SECURITY=yes
+
+# If you turn on KRB4_SECURITY, you must set all these options below.
+#
+# You can set the principle, instance, and keyfile to use seperately for
+# both the client and server.
+#
+# The instance can either be a string constant, or `HOSTNAME_INSTANCE' if
+# you want the local hostname used as the instance (ala krb_get_phost).
+#
+# The keyfile name can be either a string constant, or `KEYFILE' to use the
+# default keyfile defined in <krb.h>.
+# SERVER_HOST_PRINCIPLE="amanda"
+# SERVER_HOST_INSTANCE="amanda"
+# SERVER_HOST_KEY_FILE="/.amanda"
+# CLIENT_HOST_PRINCIPAL="rcmd"
+# CLIENT_HOST_INSTANCE=HOSTNAME_INSTANCE
+# CLIENT_HOST_KEY_FILE=KEYFILE
+# TICKET_LIFETIME=128
+
+
+# DB_STYLE             --with-db={text,db,dbm,gdbm,ndbm}
+#                      Default: text
+#                      This allows the user to force Amanda to use a
+#                      particular database library.
+# DB_STYLE=text
+
+# FORCE_MMAP           --with-mmap
+#                      Default: no
+#                      Force the use of mmap() instead of shared memory
+#                      support.
+# FORCE_MMAP=yes
+
+
+# DUMPER_SOCKET_BUFFERIING --with-buffered-dump
+#                      Default: no
+#                      Dumping sockets are buffered in the server.  This
+#                      may improve dumping speed.
+# DUMPER_SOCKET_BUFFERING=yes
+
+
+# ASSERTIONS           --with-assertions
+#                      Default: no
+#                      Turns on assertion checking, which makes Amanda a
+#                      bit bigger and slower, but will help catch errors
+#                      earlier.
+# ASSERTIONS=yes
+
+
+# DEBUGGING            --with-debugging
+#                      Default: /tmp/amanda
+#                      Turning off debugging prevents that each
+#                      program saves a transcript of what it did to a
+#                      file in /tmp/amanda for debugging purposes.  An
+#                      alternate directory can be specified too.
+# DEBUGGING=no
+# DEBUGGING=/var/amanda/debug
+
+# DEBUG_FILE_WITH_PID  --with-pid-debug-files
+#                      Default: no
+#                      Have the Amanda debugging files that are placed
+#                      in /tmp/amanda have the process ID appended to their
+#                      filename.
+# DEBUG_FILE_WITH_PID=yes
+
+
+# TESTING              --with-testing[=suffix]
+#                      Default: no
+#                      Ues alternate service names so that a new
+#                      version of amanda can be tested without preventing
+#                      a production one from being run successfully.
+#                      The used service names will have `-test' appended
+#                      to the original names, i.e., service `amanda'
+#                      will become `amanda-test'.
+#                      If anything different from `n', `no', `y', `ye' or
+#                      `yes' is specified as suffix, after the equal sign,
+#                      this suffix will be appended to the service names
+#                      after a hyphen, i.e., --with-testing=test2 will
+#                      cause service `amanda-test2' to be used.
+# TESTING=yes
+
+
+# USE_LIBTOOL          --disable-libtool
+#                      Default: yes
+#                      By default, libtool to create static/shared
+#                      libraries.  If USE_LIBTOOL is set to no, or
+#                      --disable-libtool is specified, only static
+#                      libraries will be created, and the libtool
+#                      script will only be used to link and install
+#                      programs.
+#                      A drawback of using libtool is that it will
+#                      always install libraries, even static ones,
+#                      which are not necessary for the execution of
+#                      programs.  The advantage of using libtool is
+#                      that shared libraries may be created, which
+#                      saves disk space.
+# USE_LIBTOOL=yes
+
+# with_gnu_ld          --with-gnu-ld
+#                      Default: no
+#                      Use GNU ld in order to build shared libraries
+# with_gnu_ld=yes
+
+
+# libtool_shared       --enable-shared
+#                      Default: (enabled)
+#                      Enable the creation of shared libraries
+# libtool_shared=--disable-shared
+
+
+# libtool_static       --enable-static
+#                      Default: (enabled)
+#                      Enable the creation of static libraries
+# libtool_static=--disable-static
+
+
+#
+######################################################################
diff --git a/example/disklist b/example/disklist
new file mode 100644 (file)
index 0000000..28c74dc
--- /dev/null
@@ -0,0 +1,110 @@
+# sample Amanda2 disklist file, derived from CS.UMD.EDU's disklist
+#
+# If your configuration is called, say, "csd2", then this file normally goes
+# in /etc/amanda/csd2/disklist.
+#
+# File format is:
+#
+#      hostname diskdev dumptype [spindle [interface]]
+#
+# where the dumptypes are defined by you in amanda.conf or in-line.
+
+# At our site, root partitions have a different dumptype because they
+# are of lower priority; they don't contain user data, and don't change
+# much from the department prototype.  In a crunch, they can be left for
+# last or skipped.
+
+# A SPARCstation 1+
+salty sd0a comp-root
+salty sd0g comp-user
+salty sd1g comp-user
+salty sd2a comp-root
+salty sd2g comp-user
+salty sd3c comp-user
+
+# A DECstation 3100
+slithy rz1a comp-root
+slithy rz1g comp-user
+slithy rz3a comp-root
+slithy rz3g comp-user
+
+# We don't run compression on the master host since it is going to be
+# busy enough running amanda.
+master sd0a nocomp-root -1 local
+master sd0g nocomp-user -1 local
+# note: -1 is a placeholder for the spindle number
+# the holding disk can't be dumped to itself, it uses a disktype that
+# specifies the "no-hold" option (see amanda.conf).
+master sd1c holding-disk -1 local
+
+# Compress data from a slow server on the tape server.
+# Example of inline dumptype specialization
+slowsrv / { # the line break here is mandatory
+  root-tar # copy properties of root-tar
+  compress server fast # but change the compression mode
+} # spindle and interface omitted here
+slowsrv /usr {
+  user-tar
+  exclude list ".exclude"
+  compress server fast
+} 2 le0 # no line break before spindle and interface
+
+# The chairman's disk is high priority to make sure it gets done.
+bigwig sd0a comp-root
+bigwig sd0g comp-high
+# Likewise the named databases in the root partition on our primary
+# nameserver.  Also, compression is turned off because we don't want
+# to create any unnecessary load on this baby (it's only a Sun3).
+bozo        sd0a nocomp-high
+bozo        sd0g nocomp-user
+bozo        sd4c nocomp-user
+
+# Dump Joe's NetBSD machine, with the mounted MS-DOS partition dumped
+# using tar.
+joespc  wd0a comp-root
+joespc  wd0e comp-user
+joespc /msdos comp-user-tar
+
+# Some really slow machines, like Sun2's and some Vaxstations, take
+# forever to compress their dumps: it's just not worth it.
+
+# A Sun2
+cleo     sd0a nocomp-root
+cleo     sd0g nocomp-user
+# A VaxStation
+susie         rz8a nocomp-root
+susie         rz8g nocomp-user
+
+# An example of how to separate a big disk (/diskA) in multiple smaller entry
+# using GNUTAR.
+# I suggest to always use the diskdevice in the diskname.
+# Don't forget to use the same spindle for all entry.
+hosta /diskA/all /diskA {
+       # all directories except the one that start with [a-u]
+       high-tar
+       exclude "./[a-u]*"
+       } 1
+hosta /diskA/ag /diskA {
+       # all directories that start with [a-g] except big1 and big2
+       high-tar
+       include "./[a-g]*"
+       exclude "./big1" "./big2"
+       } 1
+hosta /diskA/big /diskA {
+       # directories big1 and big2
+       high-tar
+       include "./big1" "./big2"
+       } 1
+hosta /diskA/gm /diskA {
+       # all directories that start with [h-m]
+       high-tar
+       include "./[h-m]*"
+       } 1
+hosta /diskA/nu /diskA {
+       # all directories that start with [n-u]
+       high-tar
+       include "./[n-u]*"
+       } 1
+
+
+# and so on ... well, you get the idea
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644 (file)
index 0000000..539b219
--- /dev/null
@@ -0,0 +1,58 @@
+# Makefile for amanda man-pages
+
+transform =    s,x,x,;
+
+if WANT_AMPLOT
+AMPLOT_MAN_PAGES = amplot.8
+endif
+
+COMMON_MAN_PAGES = amanda.8
+
+if WANT_SERVER
+SERVER_MAN_PAGES = amadmin.8 \
+                  amcheck.8 \
+                  amcheckdb.8 \
+                  amcleanup.8 \
+                  amdd.8 \
+                  amdump.8 \
+                  amflush.8 \
+                  amgetconf.8 \
+                  amlabel.8 \
+                  ammt.8 \
+                  amoverview.8 \
+                  amreport.8 \
+                  amrmtape.8 \
+                  amstatus.8 \
+                  amtape.8 \
+                  amtapetype.8 \
+                  amtoc.8 \
+                  amverify.8 \
+                  amverifyrun.8
+endif
+
+if WANT_RECOVER
+RECOVER_MAN_PAGES = amrecover.8
+endif
+
+if WANT_RESTORE
+RESTORE_MAN_PAGES = amrestore.8
+endif
+
+# not autoconf-generated:
+EXTRA_DIST = amplot.8 amrestore.8 amtape.8 amdd.8 ammt.8
+
+man_MANS = $(AMPLOT_MAN_PAGES) \
+          $(COMMON_MAN_PAGES) \
+          $(SERVER_MAN_PAGES) \
+          $(RECOVER_MAN_PAGES) \
+          $(RESTORE_MAN_PAGES)
+
+install-data-hook:
+       @list="$(man_MANS)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(mandir)/man8/`echo $$p|sed '$(transform)'`; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+       done
diff --git a/man/Makefile.in b/man/Makefile.in
new file mode 100644 (file)
index 0000000..d413d43
--- /dev/null
@@ -0,0 +1,550 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 man-pages
+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)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+subdir = man
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+       $(srcdir)/amadmin.8.in $(srcdir)/amanda.8.in \
+       $(srcdir)/amcheck.8.in $(srcdir)/amcheckdb.8.in \
+       $(srcdir)/amcleanup.8.in $(srcdir)/amdump.8.in \
+       $(srcdir)/amflush.8.in $(srcdir)/amgetconf.8.in \
+       $(srcdir)/amlabel.8.in $(srcdir)/amoverview.8.in \
+       $(srcdir)/amrecover.8.in $(srcdir)/amreport.8.in \
+       $(srcdir)/amrmtape.8.in $(srcdir)/amstatus.8.in \
+       $(srcdir)/amtapetype.8.in $(srcdir)/amtoc.8.in \
+       $(srcdir)/amverify.8.in $(srcdir)/amverifyrun.8.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 = amadmin.8 amanda.8 amcheck.8 amcheckdb.8 \
+       amcleanup.8 amdump.8 amflush.8 amlabel.8 amoverview.8 \
+       amrecover.8 amrmtape.8 amtoc.8 amverify.8 amstatus.8 \
+       amreport.8 amgetconf.8 amverifyrun.8 amtapetype.8
+SOURCES =
+DIST_SOURCES =
+man8dir = $(mandir)/man8
+am__installdirs = "$(DESTDIR)$(man8dir)"
+NROFF = nroff
+MANS = $(man_MANS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+transform = s,x,x,;
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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@
+@WANT_AMPLOT_TRUE@AMPLOT_MAN_PAGES = amplot.8
+COMMON_MAN_PAGES = amanda.8
+@WANT_SERVER_TRUE@SERVER_MAN_PAGES = amadmin.8 \
+@WANT_SERVER_TRUE@                amcheck.8 \
+@WANT_SERVER_TRUE@                amcheckdb.8 \
+@WANT_SERVER_TRUE@                amcleanup.8 \
+@WANT_SERVER_TRUE@                amdd.8 \
+@WANT_SERVER_TRUE@                amdump.8 \
+@WANT_SERVER_TRUE@                amflush.8 \
+@WANT_SERVER_TRUE@                amgetconf.8 \
+@WANT_SERVER_TRUE@                amlabel.8 \
+@WANT_SERVER_TRUE@                ammt.8 \
+@WANT_SERVER_TRUE@                amoverview.8 \
+@WANT_SERVER_TRUE@                amreport.8 \
+@WANT_SERVER_TRUE@                amrmtape.8 \
+@WANT_SERVER_TRUE@                amstatus.8 \
+@WANT_SERVER_TRUE@                amtape.8 \
+@WANT_SERVER_TRUE@                amtapetype.8 \
+@WANT_SERVER_TRUE@                amtoc.8 \
+@WANT_SERVER_TRUE@                amverify.8 \
+@WANT_SERVER_TRUE@                amverifyrun.8
+
+@WANT_RECOVER_TRUE@RECOVER_MAN_PAGES = amrecover.8
+@WANT_RESTORE_TRUE@RESTORE_MAN_PAGES = amrestore.8
+
+# not autoconf-generated:
+EXTRA_DIST = amplot.8 amrestore.8 amtape.8 amdd.8 ammt.8
+man_MANS = $(AMPLOT_MAN_PAGES) \
+          $(COMMON_MAN_PAGES) \
+          $(SERVER_MAN_PAGES) \
+          $(RECOVER_MAN_PAGES) \
+          $(RESTORE_MAN_PAGES)
+
+all: all-am
+
+.SUFFIXES:
+$(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  man/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  man/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
+amadmin.8: $(top_builddir)/config.status $(srcdir)/amadmin.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amanda.8: $(top_builddir)/config.status $(srcdir)/amanda.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcheck.8: $(top_builddir)/config.status $(srcdir)/amcheck.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcheckdb.8: $(top_builddir)/config.status $(srcdir)/amcheckdb.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcleanup.8: $(top_builddir)/config.status $(srcdir)/amcleanup.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amdump.8: $(top_builddir)/config.status $(srcdir)/amdump.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amflush.8: $(top_builddir)/config.status $(srcdir)/amflush.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amlabel.8: $(top_builddir)/config.status $(srcdir)/amlabel.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amoverview.8: $(top_builddir)/config.status $(srcdir)/amoverview.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amrecover.8: $(top_builddir)/config.status $(srcdir)/amrecover.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amrmtape.8: $(top_builddir)/config.status $(srcdir)/amrmtape.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amtoc.8: $(top_builddir)/config.status $(srcdir)/amtoc.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amverify.8: $(top_builddir)/config.status $(srcdir)/amverify.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amstatus.8: $(top_builddir)/config.status $(srcdir)/amstatus.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amreport.8: $(top_builddir)/config.status $(srcdir)/amreport.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amgetconf.8: $(top_builddir)/config.status $(srcdir)/amgetconf.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amverifyrun.8: $(top_builddir)/config.status $(srcdir)/amverifyrun.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amtapetype.8: $(top_builddir)/config.status $(srcdir)/amtapetype.8.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+install-man8: $(man8_MANS) $(man_MANS)
+       @$(NORMAL_INSTALL)
+       test -z "$(man8dir)" || $(mkdir_p) "$(DESTDIR)$(man8dir)"
+       @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.8*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+         else file=$$i; fi; \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           8*) ;; \
+           *) ext='8' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+         $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
+       done
+uninstall-man8:
+       @$(NORMAL_UNINSTALL)
+       @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.8*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           8*) ;; \
+           *) ext='8' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
+         rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
+       done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+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 $(MANS)
+installdirs:
+       for dir in "$(DESTDIR)$(man8dir)"; 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:
+       -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-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+       @$(NORMAL_INSTALL)
+       $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man: install-man8
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-man
+
+uninstall-man: uninstall-man8
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-libtool distdir dvi \
+       dvi-am html html-am info info-am install install-am \
+       install-data install-data-am install-exec install-exec-am \
+       install-info install-info-am install-man install-man8 \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       uninstall uninstall-am uninstall-info-am uninstall-man \
+       uninstall-man8
+
+
+install-data-hook:
+       @list="$(man_MANS)"; \
+       for p in $$list; do \
+               pa=$(DESTDIR)$(mandir)/man8/`echo $$p|sed '$(transform)'`; \
+               echo chown $(BINARY_OWNER) $$pa; \
+               chown $(BINARY_OWNER) $$pa; \
+               echo chgrp $(SETUID_GROUP) $$pa; \
+               chgrp $(SETUID_GROUP) $$pa; \
+       done
+# 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/man/amadmin.8.in b/man/amadmin.8.in
new file mode 100644 (file)
index 0000000..180bcf8
--- /dev/null
@@ -0,0 +1,363 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.de P1
+\fB\\$1\fP \\$2 \fI\\$3\fP \\$4 \fI\\$5\fP \\$6 \\$7
+..
+.de P2
+\fB\\$1\fP \fI\\$2\fP \\$3 \\$4 \\$5
+..
+.de P3
+\fB\\$1\fP \\$2 \fI\\$3\fP \\$4 \fI\\$5\fP \\$6 \\$7
+..
+.TH AMADMIN 8
+.SH NAME
+amadmin \- administrative interface to control Amanda backups
+.SH SYNOPSIS
+.B amadmin
+.I config
+.I command
+[
+.I command options
+]
+.SH DESCRIPTION
+.B Amadmin
+performs various administrative tasks on the
+.I config
+Amanda configuration.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH COMMANDS
+Commands that take a
+.I hostname
+[
+.I disks
+]
+parameter pair operate on all disks in the
+.I disklist
+for that
+.I hostname
+if no disks are specified.
+Where
+.I hostname
+is also marked as being optional,
+the command operates on all hosts and disks in the
+.IR disklist .
+Both
+.I hostnames
+and
+.I disk
+are special expression, see the "HOST & DISK EXPRESSION" section
+of 
+.IR amanda (8)
+for a description.
+.LP
+.TP
+.B version
+Show the current version and some compile time and runtime parameters.
+The
+.I config
+parameter must be present but is ignored.
+.TP
+.P1 force-bump [ hostname [ disks ]* ]+
+Force the
+.I disks
+on
+.I hostname
+to bump to a new incremental level during the next Amanda run.
+.TP
+.P1 force-no-bump [ hostname [ disks ]* ]+
+Force the
+.I disks
+on
+.I hostname
+to not bump to a new incremental level during the next Amanda run.
+.TP
+.P1 unforce-bump [ hostname [ disks ]* ]+
+Undo a previous
+.B force-bump
+or
+.B force-no-bump
+command.
+.TP
+.P1 force [ hostname [ disks ]* ]+
+Force the
+.I disks
+on
+.I hostname
+to do a full (level 0) backup during the next Amanda run.
+.TP
+.P1 unforce [ hostname [ disks ]* ]+
+Undo a previous
+.B force
+command.
+.TP
+.P2 reuse tapelabel [ ... ]
+The tapes listed
+will be available for reuse at their point in the tape cycle.
+.TP
+.P2 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
+.B amanda.conf
+.I tapecycle
+value, Amanda will request new tapes until the count is satisfied again.
+.TP
+.P1 due [ hostname [ disks ]* ]*
+Show when the next full dump is due.
+.TP
+.P3 "find\fP [ \fB--sort\fP \fBhkdlb\fP ]\fB" [ 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.
+.IP
+The
+.B --sort
+option changes the sort order using the following flags:
+.RS
+.LP
+.de SO
+\fB\\$1\fP     \\$2
+.br
+..
+.SO h "host name"
+.SO k "disk name"
+.SO d "dump date"
+.SO l "backup level"
+.SO b "tape label"
+.RE
+.IP
+An uppercase letter reverses the sort order for that key.
+The default sort order is
+.BR hkdlb .
+.TP
+.P1 delete [ hostname [ disks ]* ]+
+Delete the specified
+.I disks
+on
+.I hostname
+from the Amanda
+database.
+.IP
+Note: if you do not also remove the disk from the
+.I disklist
+file, Amanda will treat it as a new disk during the next run.
+.TP
+.B tape
+Display the tape(s) Amanda expects to write to during the next run.
+See also
+.IR amcheck (8).
+.TP
+.B bumpsize
+Display the current bump threshold parameters, calculated for all backup
+levels.
+.TP
+.P3 "balance\fP [ \fB--days\fP \fB<num>\fP ]\fB"
+Display the distribution of full backups throughout the dump schedule.
+.TP
+.P1 export [ hostname [ disks ]* ]*
+Convert records from the Amanda database
+to a text format that may be transmitted to another Amanda
+machine and
+.BR import ed.
+.TP
+.B import
+Convert
+.BR export ed
+records read from standard input to a form Amanda uses
+and insert them into the database on this machine.
+.TP
+.P1 disklist [ hostname [ disks ]* ]*
+Display the
+.I disklist
+information for each of the
+.I disks
+on
+.I hostname
+(or all hosts).
+Mostly used for debugging.
+.TP
+.P1 info [ hostname [ disks ]* ]*
+Display the
+database record for each of the
+.I disks
+on
+.IR hostname
+(or all hosts).
+Mostly used for debugging.
+.SH EXAMPLES
+Request three specific file systems on
+.I machine-a
+get a full level 0 backup during the next Amanda run.
+.LP
+.RS
+.EX
+$ amadmin @DEFAULT_CONFIG@ force machine-a / /var /usr
+amadmin: machine-a:/ is set to a forced level 0 tonight.
+amadmin: machine-a:/var is set to a forced level 0 tonight.
+amadmin: machine-a:/usr is set to a forced level 0 tonight.
+.EE
+.RE
+.LP
+Request all file systems on
+.I machine-b
+get a full level 0 backup during the next Amanda run.
+.RE
+.LP
+.RS
+.EX
+$ amadmin @DEFAULT_CONFIG@ force machine-b
+amadmin: machine-b:/ is set to a forced level 0 tonight.
+amadmin: machine-b:/var is set to a forced level 0 tonight.
+amadmin: machine-b:/usr is set to a forced level 0 tonight.
+amadmin: machine-b:/home is set to a forced level 0 tonight.
+.EE
+.RE
+.LP
+Undo the previous
+.B force
+request for
+.I /home
+on
+.IR machine-b .
+The other file systems will still get a full level 0 backup.
+.LP
+.RS
+.EX
+$ amadmin @DEFAULT_CONFIG@ unforce machine-b /home
+amadmin: force command for machine-b:/home cleared.
+.EE
+.RE
+.LP
+Locate backup images of
+.I /var
+from
+.IR machine-c .
+The
+.I tape or file
+column displays either a tape label or a filename depending on whether
+the image is on tape or is still in the holding disk.
+If the image is on tape, the
+.I file
+column tells you which file on the tape has the image
+(file number zero is a tape label).
+This column shows zero and is not meaningful if the image
+is still in the holding disk.
+The
+.I status
+column tells you whether the backup was successful or had
+some type of error.
+.LP
+.RS
+.EX
+$ amadmin @DEFAULT_CONFIG@ 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
+.EE
+.RE
+.LP
+Forget about the
+.I /workspace
+disk on
+.IR machine-d .
+If you do not also remove the disk from the
+.I disklist
+file, Amanda will treat it as a new disk during the next run.
+.LP
+.RS
+.EX
+$ amadmin @DEFAULT_CONFIG@ delete machine-d /workspace
+amadmin: machine-d:/workspace deleted from database.
+amadmin: NOTE: you'll have to remove these from the disklist yourself.
+.EE
+.RE
+.LP
+Find the next tape Amanda will use
+(in this case, 
+.IR 123456 ).
+.LP
+.RS
+.EX
+$ amadmin @DEFAULT_CONFIG@ tape
+The next Amanda run should go onto tape 123456 or a new tape.
+.EE
+.RE
+.LP
+Show how well full backups are balanced across the dump cycle.
+The
+.I due-date
+column is the day the backups are due for a full backup.
+.I #fs
+shows the number of filesystems doing full backups that night, and
+.I orig KB
+and
+.I out KB
+show the estimated total size of the backups
+before and after any compression, respectively.
+.LP
+The
+.I 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 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 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.
+.LP
+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 eight days).
+.LP
+.RS
+.EX
+$ amadmin @DEFAULT_CONFIG@ balance
+ due-date  #fs   orig KB    out KB  balance
+-------------------------------------------
+11/10 Mon   21    930389    768753    +5.1%
+11/11 Tue   29   1236272    733211    +0.2%
+11/12 Wed   31   1552381    735796    +0.6%
+11/13 Thu   23   1368447    684552    -6.4%
+11/14 Fri   32   1065603    758155    +3.6%
+11/15 Sat   14   1300535    738430    +0.9%
+11/16 Sun   31   1362696    740365    +1.2%
+11/17 Mon   30   1427936    773397    +5.7%
+11/18 Tue   11   1059191    721786    -1.3%
+11/19 Wed   19   1108737    661867    -9.5%
+-------------------------------------------
+TOTAL      241  12412187   7316312   731631  (estimated 8 runs per dumpcycle)
+.EE
+.SH FILES
+@CONFIG_DIR@/\fIconfig\fP/amanda.conf
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8),
+amcheck(8),
+amdump(8),
+amrestore(8)
diff --git a/man/amanda.8.in b/man/amanda.8.in
new file mode 100644 (file)
index 0000000..1e618f9
--- /dev/null
@@ -0,0 +1,2131 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.de P1
+\fB\\$1\fP \\$2 \fI\\$3\fP \\$4 \fI\\$5\fP \\$6 "\fI\\$7\fP" \\$8
+..
+.TH AMANDA 8
+.SH NAME
+amanda \- Advanced Maryland Automatic Network Disk Archiver
+.SH SYNOPSIS
+.B amdump
+.I config
+.br
+.B amflush
+[
+.B \-f
+]
+.I config
+.br
+.B amcleanup
+.I config
+.br
+.B amrecover
+[
+.I config
+] [
+.I options
+]
+.br
+.B amrestore
+[
+.I options
+]
+.I tapedevice
+[
+.I hostname
+[
+.I diskname
+]]
+.br
+.B amlabel
+.I config label
+[
+.B slot
+.I slot
+]
+.br
+.B amcheck
+[
+.I options
+]
+.I config
+.br
+.B amadmin
+.I config
+.I command
+[
+.I options
+]
+.br
+.B amtape
+.I config
+.I command
+[
+.I options
+]
+.br
+.B amverify
+.I config
+.br
+.B amrmtape
+[
+.I options
+]
+.I config label
+.br
+.B amstatus
+.I config
+[
+.I options
+]
+.br
+.B amoverview
+.I config
+[
+.I options
+]
+.br
+.B amplot
+[
+.I options
+]
+.I amdump-files
+.br
+.B amreport
+[
+.I config
+]
+[
+.I options
+]
+.br
+.B amtoc
+[
+.I options
+]
+.I logfile
+.br
+.B amcheckdb
+.I config
+.br
+.B amgetconf
+[
+.I config
+]
+.I parameter
+.br
+.SH 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 reference.
+.LP
+Here are all the Amanda commands.
+Each one has its own manual page.
+See them for all the gory details.
+.TP
+.B amdump
+Take care of automatic Amanda backups.
+This is normally executed by
+.B cron
+on a computer called the
+.I tape server host
+and requests backups of file systems located on
+.I backup
+.IR clients .
+.B Amdump
+backs up all disks in the
+.I disklist
+file (discussed below) to tape or, if there is a problem, to a special
+.I holding
+.IR disk .
+After all backups are done,
+.B amdump
+sends mail reporting failures and successes.
+.TP
+.B amflush
+Flush backups from the holding disk to tape.
+.B Amflush
+is used after
+.B amdump
+has reported it could not write backups to tape for some reason.
+When this happens, backups stay in the holding disk.
+Run
+.B amflush
+after the tape problem is corrected
+to write backups from the holding disk to tape.
+.TP
+.B amcleanup
+Clean up after an interrupted
+.BR amdump .
+This command is only needed if
+.B amdump
+was unable to complete for some reason, usually because the
+tape server host crashed while
+.B amdump
+was running.
+.TP
+.B amrecover
+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
+.B amrestore
+and a restore program (e.g.\&
+.BR tar )
+to actually recover the files.
+.TP
+.B amrestore
+Read an Amanda tape, searching for requested backups.
+.B Amrestore
+is suitable for everything from interactive restores of single files
+to a full restore of all partitions on a failed disk.
+.TP
+.B amlabel
+Write an Amanda format label onto a tape.
+All Amanda tapes must be labeled with
+.BR amlabel .
+.B Amdump
+and
+.B amflush
+will not write to an unlabeled tape (see TAPE MANAGEMENT below).
+.TP
+.B amcheck
+Verify the correct tape is mounted
+and all file systems on all backup client systems
+are ready to be backed up.
+Often run by
+.B cron
+before
+.B amdump
+to generate a mail warning that backups might fail
+unless corrective action is taken.
+.TP
+.B amadmin
+Take care of administrative tasks like finding out which
+tapes are needed to restore a filesystem,
+forcing hosts to do full backups of selected disks
+and looking at schedule balance information.
+.TP
+.B amtape
+Take care of tape changer control operations like loading particular tapes,
+ejecting tapes
+and scanning the tape storage slots.
+.TP
+.B amverify
+Check Amanda backup tapes for errors.
+.TP
+.B amrmtape
+Delete a tape from the Amanda databases.
+.TP
+.B amstatus
+Report the status of a running or completed
+.BR amdump .
+.TP
+.B amoverview
+Display a chart of hosts and file systems backed up every run.
+.TP
+.B amplot
+Generate utilization plots of Amanda runs for performance tuning.
+.TP
+.B amreport
+Generate an Amanda summary E-mail report.
+.TP
+.B amtoc
+Generate table of content files for Amanda tapes.
+.TP
+.B amcheckdb
+Verify every tape Amanda knows about is consistent in the database.
+.TP
+.B amgetconf
+Look up parameters in the Amanda configuration file.
+.SH CONFIGURATION
+There are three user\-editable files that control the behavior of Amanda.
+The first is
+.B amanda.conf,
+the main configuration file.
+It contains parameters to customize Amanda for the site.
+Second is the
+.I disklist
+file, which lists hosts and disk partitions to back up.
+Third is the
+.I tapelist
+file, which lists tapes that are currently active.
+These files are described in more detail in the following sections.
+.LP
+All files are stored in individual configuration
+directories under @CONFIG_DIR@.
+A site will often have more than
+one configuration.
+For example, it might have a
+.I normal
+configuration for everyday backups and an
+.I archive
+configuration for infrequent full archival backups.
+The configuration files would be stored under directories
+@CONFIG_DIR@/normal/ and
+@CONFIG_DIR@/archive/, respectively.
+Part of the job of an Amanda administrator is to create,
+populate and maintain these directories.
+.LP
+All log and database files generated by Amanda go in corresponding
+directories somewhere.
+The exact location is controlled by entries in
+.BR 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/.
+.LP
+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.
+.LP
+Detailed information about
+.B amdump
+runs are stored in files named
+.BI amdump. NN
+where
+.I NN
+is a sequence number, with 1 being the most recent file.
+.B Amdump
+rotates these files each run, keeping roughly the last
+.B tapecycle
+(see below)
+worth of them.
+.LP
+The file used by
+.B amreport
+to generate the mail summary is named
+.BI log. YYYYMMDD.NN
+where
+.I YYYYMMDD
+is the datestamp of the start of the
+.B amdump
+run and
+.I NN
+is a sequence number started at 0.
+At the end of each
+.B amdump
+run,
+log files for runs whose tapes have been reused are renamed
+into a subdirectory of the main log directory (see the
+.B logdir
+parameter below)
+named
+.BR oldlog .
+It is up to the Amanda administrator to remove them from this
+directory when desired.
+.LP
+Index (backup image catalogue) files older than the full dump
+matching the oldest backup image for a given client and disk
+are removed by
+.B amdump
+at the end of each run.
+.SH CONFIG FILE PARAMETERS
+.de BS
+\fB\\$1\fP\ \fI"\\$2"\fP
+..
+.de BN
+\fB\\$1\fP\ \fI\\$2\fP
+..
+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
+.B amanda.conf
+if the default is suitable.
+.LP
+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.
+.LP
+Keywords are case insensitive, i.e.\&
+.B mailto
+and
+.B MailTo
+are treated the same.
+.LP
+Integer arguments may have one of the following (case insensitive) suffixes,
+some of which have a multiplier effect:
+.RS
+.TP
+.B "b byte bytes"
+Some number of bytes.
+.TP
+.B "bps"
+Some number of bytes per second.
+.TP
+.B "k kb kbyte kbytes kilobyte kilobytes"
+Some number of kilobytes (bytes*1024).
+.TP
+.B "kps kbps"
+Some number of kilobytes per second (bytes*1024).
+.TP
+.B "m mb meg mbyte mbytes megabyte megabytes"
+Some number of megabytes (bytes*1024*1024).
+.TP
+.B "mps mbps"
+Some number of megabytes per second (bytes*1024*1024).
+.TP
+.B "g gb gbyte gbytes gigabyte gigabytes"
+Some number of gigabytes (bytes*1024*1024*1024).
+.TP
+.B "tape tapes"
+Some number of tapes.
+.TP
+.B "day days"
+Some number of days.
+.TP
+.B "week weeks"
+Some number of weeks (days*7).
+.RE
+.LP
+The value
+.B inf
+may be used in most places where an integer is expected
+to mean an infinite amount.
+.LP
+Boolean arguments may have any of the values
+.BR y ,
+.BR yes ,
+.BR t ,
+.B true
+or
+.B on
+to indicate a true state, or
+.BR n ,
+.BR no ,
+.BR f ,
+.BR false
+or
+.B off
+to indicate a false state.
+If no argument is given,
+.B true
+is assumed.
+.LP
+.TP
+.BS org string
+Default:
+.IR @DEFAULT_CONFIG@ .
+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.
+.TP
+.BS mailto string
+Default:
+.IR operators .
+A space separated list of recipients for mail reports.
+.TP
+.BN dumpcycle int
+Default:
+.IR "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.
+.IP
+Note that this parameter may also be set in a specific
+.B dumptype
+(see below).
+This value sets the default for all
+.BR dumptype s
+so must appear in
+.B amanda.conf
+before any
+.BR dumptype s
+are defined.
+.TP
+.BN runspercycle int
+Default:
+.IR "same as dumpcycle" .
+The number of amdump runs in 
+.B dumpcycle
+days.
+A value of 0 means the same value as 
+.BR dumpcycle .
+A value of -1 means guess the number of runs from the
+.I tapelist
+file, 
+which is the number of tapes used in the last 
+.B dumpcycle
+days / 
+.BR runtapes .
+.TP
+.BN tapecycle int
+Default:
+.IR "15 tapes" .
+The mininum number of tapes in the active tape cycle.
+You can have more tapes in your active tape cycle.
+It means that you must write at least
+.B tapecycle
+tape before a tape
+is overwritten.
+A tape marked as 
+.B no-reuse
+is not in the active tape cycle.
+.IP
+Amanda will accept any tape for writting if it is not in the last
+.B tapecycle
+tapes used.
+.IP
+This must be at least one larger than the
+number of Amanda runs done during a dump cycle
+(see the
+.B dumpcycle
+parameter)
+times the number of tapes used per run
+(see the
+.B runtapes
+parameter).
+.IP
+For instance, if
+.B dumpcycle
+is set to 14 days,
+one Amanda run is done every day (Sunday through Saturday),
+and
+.B runtapes
+is set to one,
+then
+.B tapecycle
+must be at least 15 (14 days * one run/day * one tape/run + one tape).
+.IP
+In practice, there should be several extra tapes
+to allow for schedule adjustments or disaster recovery.
+.TP
+.BS dumpuser string
+Default:
+.IR @CLIENT_LOGIN@ .
+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
+.I .rhosts
+or
+.IR .amandahosts ,
+depending on how the Amanda software was built.
+.TP
+.BS printer string
+Printer to use when doing tape labels.
+See the
+.B lbl-templ
+.B tapetype
+option.
+.TP
+.BS tapedev string
+Default:
+.IR @DEFAULT_TAPE_DEVICE@ .
+The path name of the non-rewinding tape device.
+Non-rewinding tape device names often have an 'n' in the name,
+e.g.
+.IR /dev/rmt/0mn ,
+however this is operating system specific and you should consult
+that documentation for detailed naming information.
+.IP
+If a tape changer is configured
+(see the
+.B tpchanger
+option), this option might not be used.
+.IP
+If the
+.B null
+output driver is selected
+(see the
+.B OUTPUT DRIVERS
+section later for more information),
+programs such as
+.B 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
+.B record
+option set to
+.IR no .
+.TP
+.BS rawtapedev string
+Default:
+.IR @DEFAULT_RAW_TAPE_DEVICE@ .
+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.
+.TP
+.BS tpchanger string
+Default:
+.IR 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.
+.IP
+If a tape changer is configured, choose one of the changer scripts
+(e.g.\&
+.BR chg-scsi )
+and enter that here.
+.TP
+.BS changerdev string
+Default:
+.IR @DEFAULT_CHANGER_DEVICE@ .
+A tape changer configuration parameter.
+Usage depends on the particular changer defined with the
+.B tpchanger
+option.
+.TP
+.BS changerfile string
+Default:
+.IR /usr/adm/amanda/log/changer\-status .
+A tape changer configuration parameter.
+Usage depends on the particular changer defined with the
+.B tpchanger
+option.
+.TP
+.BN runtapes int
+Default:
+.IR 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.
+.IP
+If a tape changer is configured, this may be set larger than one to
+let Amanda write to more than one tape.
+.IP
+Note that this is an upper bound on the number of tapes,
+and Amanda may use less.
+.IP
+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.
+.TP
+.BN maxdumpsize int
+Default:
+.IR runtapes * tape_length .
+Maximum number of bytes the planner will schedule for a run.
+.TP
+.BN taperalgo [first|firstfit|largest|largestfit|smallest|last]
+Default:
+.IR first .
+The algorithm use to choose which dump image to send to the taper.
+.RS
+.TP
+.B first
+First in first out.
+.TP
+.B firstfit
+The first dump image that will fit on the current tape.
+.TP
+.B largest
+The largest dump image.
+.TP
+.B largestfit
+The largest dump image that will fit on the current tape.
+.TP
+.B smallest
+The smallest dump image.
+.TP
+.B last
+Last in first out.
+.RE
+.LP
+.BS labelstr string
+Default:
+.IR .* .
+The tape label constraint regular expression.
+All tape labels
+generated (see
+.BR 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.
+.TP
+.BS tapetype string
+Default:
+.IR EXABYTE .
+The type of tape drive associated with
+.B tapedev
+or
+.BR tpchanger .
+This refers to one of the defined
+.BR tapetype s
+in the config file (see below),
+which specify various tape parameters,
+like the
+.BR length ,
+.B filemark
+size, and
+.B speed
+of the tape media and device.
+.TP
+.BN ctimeout int
+Default:
+.IR "30 seconds" .
+Maximum amount of time that
+.B amcheck 
+will wait for each client host.
+.TP
+.BN dtimeout int
+Default:
+.IR "1800 seconds" .
+Amount of idle time per disk on a given client that a
+.B dumper
+running from within
+.B amdump
+will wait before it fails with a data timeout error.
+.TP
+.BN etimeout int
+Default:
+.IR "300 seconds" .
+Amount of time per disk on a given client that the
+.B planner
+step of
+.B amdump
+will wait to get the dump size estimates.
+For instance, with the default of 300 seconds and four disks on client A, 
+.B 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.
+.TP
+.BN netusage int
+Default:
+.IR "300 Kbps" .
+The maximum network bandwidth allocated to Amanda, in Kbytes per second.
+See also the
+.B interface
+section.
+.TP
+.BN inparallel int
+Default:
+.IR 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.
+.TP
+.BS dumporder string
+Default:
+.IR "tttTTTTTTT" .
+The priority order of each dumper:
+.RS
+.RS
+.nf
+s: smallest size
+S: largest size
+t: smallest time
+T: largest time
+b: smallest bandwidth
+B: largest bandwidth
+.fi
+.RE
+.RE
+.TP
+.BN maxdumps int
+Default:
+.IR 1 .
+The maximum number of backups from a single host that Amanda will
+attempt to run in parallel.
+See also the
+.B inparallel
+option.
+.IP
+Note that this parameter may also be set in a specific
+.B dumptype
+(see below).
+This value sets the default for all
+.BR dumptype s
+so must appear in
+.B amanda.conf
+before any
+.BR dumptype s
+are defined.
+.TP
+.BN bumpsize int
+Default:
+.IR "10 Mbytes" .
+The minimum savings required to trigger an automatic
+bump from one incremental level to the next.
+If Amanda determines that the next higher backup level
+will be this much smaller than the current level,
+it will do the next level.
+See also the
+.B bumpmult
+option.
+.TP
+.BN bumpmult float
+Default:
+.IR 1.5 .
+The bump size multiplier.
+Amanda multiplies
+.B 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
+.B bumpsize
+and
+.BR 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.
+.TP
+.BN bumpdays int
+Default:
+.IR "2 days" .
+To insure redundancy in the dumps, Amanda keeps filesystems at the
+same incremental level for at least
+.B bumpdays
+days, even if the other bump threshold criteria are met.
+.TP
+.BS diskfile string
+Default:
+.IR disklist .
+The file name for the
+.I disklist
+file holding client hosts, disks and other client dumping information.
+.TP
+.BS infofile string
+Default:
+.IR /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.
+.TP
+.BS logdir string
+Default:
+.IR /usr/adm/amanda .
+The directory for the
+.B amdump
+and
+.B log
+files.
+.TP
+.BS indexdir string
+Default
+.IR /usr/adm/amanda/index .
+The directory where index files (backup image catalogues) are stored.
+Index files are
+only generated for filesystems whose
+.B dumptype
+has the
+.B index
+option enabled.
+.TP
+.BS tapelist string
+Default:
+.IR tapelist .
+The file name for the active
+.I tapelist
+file.
+Amanda maintains this file with information about the active set of tapes.
+.TP
+.BN tapebufs int
+Default:
+.IR 20 .
+The number of buffers used by the
+.B taper
+process run by
+.B amdump
+and
+.B 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.
+.TP
+.BN reserve number
+Default:
+.IR 100 (percent).
+The amount of holding-disk space that should not be used for full
+backups if no tape is available.
+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.
+.TP
+.BN autoflush bool
+Default:
+.IR off .
+Whether an amdump run will flush the dump already on holding disk to tape.
+.TP
+.BN amrecover_do_fsf bool
+Default:
+.IR off .
+Amrecover will call amrestore with the -f flag for faster positioning of the tape.
+.TP
+.BN amrecover_check_label bool
+Default:
+.IR off .
+Amrecover will call amrestore with the -l flag to check the label.
+.TP
+.BS 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.
+.TP
+.BS columnspec string
+Defines the width of columns
+.B amreport
+should use.
+.I 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:
+.RS
+.IP + 2
+the name of the column, which may be:
+.LP
+.RS
+.nf
+Compress (compression ratio)
+Disk (client disk name)
+DumpRate (dump rate in KBytes/sec)
+DumpTime (total dump time in hours:minutes)
+HostName (client host name)
+Level (dump level)
+OrigKB (original image size in KBytes)
+OutKB (output image size in KBytes)
+TapeRate (tape writing rate in KBytes/sec)
+TapeTime (total tape time in hours:minutes)
+.fi
+.RE
+.IP + 2
+the amount of space to display before the column (used to get whitespace
+between columns).
+.IP + 2
+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.
+.RE
+.LP
+.RS
+Here is an example:
+.LP
+.EX
+     columnspec "Disk=1:18,HostName=0:10,OutKB=1:7"
+.EE
+.LP
+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.
+.RE
+.TP
+.BS includefile string
+Default:
+.IR 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.
+.SH "HOLDINGDISK SECTION"
+The
+.B amanda.conf
+file may define one or more holding disks used as buffers to hold
+backup images before they are written to tape.
+The syntax is:
+.LP
+.RS
+.EX
+holdingdisk \fIname\fP {
+    \fIholdingdisk\-option\fP \fIholdingdisk\-value\fP
+    \fI...\fP
+}
+.EE
+.RE
+.LP
+.I Name
+is a logical name for this holding disk.
+.LP
+The options and values are:
+.LP
+.TP
+.BS comment string
+Default:
+.IR none .
+A comment string describing this holding disk.
+.TP
+.BS directory disk
+Default:
+.IR /dumps/amanda .
+The path to this holding area.
+.TP
+.BN use int
+Default:
+.IR "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 that value.
+.TP
+.BN chunksize int
+Default:
+.IR "1 Gb" .
+Holding disk chunk size.
+Dumps larger than the specified size will be stored in multiple
+holding disk files.
+The size of each 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.
+.IP
+If 0 is specified, Amanda will create holding disk chunks as large as
+((INT_MAX/1024)-64) Kbytes.
+.IP
+Each holding disk chunk includes a 32 Kbyte header, so the minimum
+chunk size is 64 Kbytes (but that would be really silly).
+.IP
+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.
+.SH "DUMPTYPE SECTION"
+The
+.B amanda.conf
+file may define multiple sets of backup options and
+refer to them by name from the
+.B disklist
+file.
+For instance, one set of options might be defined for file systems
+that can benefit from high compression,
+another set that does not compress well,
+another set for file systems that should always get a full backup
+and so on.
+.LP
+A set of backup options are entered in a
+.B dumptype
+section, which looks like this:
+.LP
+.RS
+.EX
+define dumptype \fIname\fP {
+    \fIdumptype\-option\fP \fIdumptype\-value\fP
+    \fI...\fP
+}
+.EE
+.RE
+.LP
+.I Name
+is the name of this set of backup options.
+It is referenced from the
+.I disklist
+file.
+.LP
+Some of the options in a
+.B dumptype
+section are the same as those in the main part of
+.BR amanda.conf .
+The main option value is used to set the default for all
+.B dumptype
+sections.
+For instance, setting
+.B dumpcycle
+to 50 in the main part of the config file causes all following
+.B dumptype
+sections to start with that value,
+but the value may be changed on a section by section basis.
+Changes to variables in the main part of the config file must be
+done before (earlier in the file) any
+.BR dumptype s
+are defined.
+.LP
+The dumptype options and values are:
+.LP
+.TP
+.BS auth string
+Default:
+.IR bsd .
+Type of authorization to perform between tape server and backup client hosts.
+May be
+.B krb4
+to use Kerberos\-IV authorization.
+.TP
+.BS comment string
+Default:
+.IR none .
+A comment string describing this set of backup options.
+.TP
+\fBcomprate\fP \fIfloat\fP [, \fIfloat\fP ]
+Default:
+.IR 0.50 ,
+.IR 0.50 .
+The expected full and incremental compression factor 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.
+.TP
+.BS "compress [client|server]" string
+Default:
+.IR "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.
+.IP
+For either type of compression, Amanda also allows the selection
+of two styles of compression.
+.B Best
+is the best compression available, often at the expense of CPU overhead.
+.B Fast
+is often not as good a compression as
+.BR best ,
+but usually less CPU overhead.
+.IP
+So the
+.B compress
+options line may be one of:
+.LP
+.RS
+.RS
+.nf
+compress none
+compress [client] fast
+compress [client] best
+compress server fast
+compress server best
+.fi
+.RE
+.RE
+.IP
+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
+.B mt
+option),
+Amanda (software) compression should be disabled.
+.TP
+.BN dumpcycle int
+Default:
+.IR "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 to zero tries to do a full backup each run.
+.TP
+.P1 exclude [ list|file ][[optional][ append ][ "string" ]+]
+Default:
+.IR file .
+There is two exclude list
+.B exclude file
+and
+.B exclude list.
+With
+.B exclude file
+, the
+.I string
+is a gnutar exclude expression. With
+.B exclude list
+, the
+.I string
+is a file name on the client containing gnutar exclude expression.
+.IP
+All exclude expression are concatenated in one file and passed to gnutar as a
+.B \-\-exclude\-from
+argument.
+.IP
+With the
+.B append
+keyword, the
+.I string
+are appended to the current value of the list, without it, the
+.I string
+overwrite the list.
+.IP
+If
+.B optional
+is specified for
+.B exclude list,
+then amcheck will not complain if the file doesn't exist or is not readable.
+.IP
+For
+.B exclude list,
+If the file name is relative,
+the disk name being backed up is prepended.
+So if this is entered:
+.LP
+.EX
+    exclude list ".amanda.excludes"
+.EE
+.IP
+the actual file use would be
+.I /var/.amanda.excludes
+for a backup of
+.IR /var ,
+.I /usr/local/.amanda.excludes
+for a backup of
+.IR /usr/local ,
+and so on.
+.TP
+.BS holdingdisk boolean
+Default:
+.IR 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 refer to a dumptype with
+.B holdingdisk
+set to
+.I no
+to avoid backing up the holding disk into itself.
+.TP
+.BS ignore boolean
+Default:
+.IR no .
+Whether disks associated with this backup type should be backed up or not.
+This option is useful when the
+.I disklist
+file is shared among several configurations,
+some of which should not back up all the listed file systems.
+.TP
+.P1 include [ list|file ][[optional][ append ][ "string" ]+]
+Default:
+.I file
+".".
+There is two include list
+.B include file
+and
+.B include list.
+With
+.B include file
+, the
+.I string
+is a glob expression. With
+.B include list
+, the
+.I string
+is a file name on the client containing glob expression.
+.IP
+All include expression are expanded by amanda and concatenated in one file and passed to gnutar as a
+.B \-\-files\-from
+argument. They must start with "./" and containing no other "/".
+.IP
+With the
+.B append
+keyword, the
+.I string
+are appended to the current value of the list, without it, the
+.I string
+overwrite the list.
+.IP
+If
+.B optional
+is specified for
+.B include list,
+then amcheck will not complain if the file doesn't exist or is not readable.
+.IP
+For
+.B include list,
+If the file name is relative,
+the disk name being backed up is prepended.
+.TP
+.BS index boolean
+Default:
+.IR no .
+Whether an index (catalogue) of the backup should be generated and
+saved in
+.BR indexdir .
+These catalogues are used by the
+.B amrecover
+utility.
+.TP
+.BS kencrypt boolean
+Default:
+.IR no .
+Whether the backup image should be encrypted by Kerberos as it is sent
+across the network from the backup client host to the tape server host.
+.TP
+.BS maxdumps int
+Default:
+.IR 1 .
+The maximum number of backups from a single host that Amanda will
+attempt to run in parallel.
+See also the main section
+.B inparallel
+option.
+.TP
+.BS maxpromoteday int
+Default:
+.IR 10000 .
+The Maximum number of day for a promotion, set it 0 if you don't want
+promotion, set it to 1 or 2 if your disk get overpromoted.
+.TP
+.BS priority string
+Default:
+.IR 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
+.BR high (2),
+.BR medium (1),
+.BR low (0)
+or a number of your choice.
+.TP
+.BS program string
+Default:
+.IR DUMP .
+The type of backup to perform.
+Valid values are
+.B DUMP
+for the native operating system backup program, and
+.B GNUTAR
+to use GNU tar or to do Samba PC backups.
+.TP
+.BS record boolean
+Default:
+.IR yes .
+Whether to ask the backup program to update its
+database (e.g.\&
+.IR /etc/dumpdates
+for DUMP or 
+.IR @GNUTAR_LISTED_INCREMENTAL_DIRX@
+for GNUTAR) of time stamps.
+This is normally enabled for daily backups and turned off
+for periodic archival runs.
+.TP
+.BS skip\-full boolean
+Default:
+.IR no .
+If
+.I true
+and
+.B 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 configuration; this
+is probably a bug.
+.TP
+.BS skip\-incr boolean
+Default:
+.IR no .
+If
+.I true
+and
+.B planner
+has scheduled an incremental backup, these disks will be skipped.
+.TP
+.BS starttime int
+Default:
+.IR none .
+Backups will not start until after this time of day.
+The value should be hh*100+mm, e.g.\& 6:30PM (18:30) would be entered as
+.BR 1830 .
+.TP
+.BS strategy string
+Default:
+.IR standard .
+Strategy to use when planning what level of backup to run next.
+Values are:
+.LP
+.RS
+.TP
+.B standard
+The standard Amanda schedule.
+.TP
+.B nofull
+Never do full backups, only level 1 incrementals.
+.TP
+.B noinc
+Never do incremental backups, only full dumps.
+.TP
+.B skip
+Never do backups (useful when sharing the
+.I disklist
+file).
+.TP
+.B 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 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, which is probably a
+bug.
+.RE
+.LP
+The following
+.B dumptype
+entries are predefined by Amanda:
+.LP
+.RS
+.EX
+define dumptype no-compress {
+    compress none
+}
+define dumptype compress-fast {
+    compress client fast
+}
+define dumptype compress-best {
+    compress client best
+}
+define dumptype srvcompress {
+    compress server fast
+}
+define dumptype bsd-auth {
+    auth bsd
+}
+define dumptype krb4-auth {
+    auth krb4
+}
+define dumptype no-record {
+    record no
+}
+define dumptype no-hold {
+    holdingdisk no
+}
+define dumptype no-full {
+    skip-full yes
+}
+.EE
+.RE
+.LP
+In addition to options in a
+.B dumptype
+section, one or more other
+.B dumptype
+names may be entered, which make this
+.B dumptype
+inherit options from other
+previously defined
+.BR dumptype s.
+For instance, two sections might be the same except for the
+.B record
+option:
+.LP
+.RS
+.EX
+define dumptype normal {
+    comment "Normal backup, no compression, do indexing"
+    no-compress
+    index yes
+    maxdumps 2
+}
+define dumptype testing {
+    comment "Test backup, no compression, do indexing, no recording"
+    normal
+    record no
+}
+.EE
+.RE
+.LP
+Amanda provides a
+.B dumptype
+named
+.I global
+in the sample
+.B amanda.conf
+file that all
+.BR dumptype s
+should reference.
+This provides an easy place to make changes that will affect
+every
+.BR dumptype .
+.SH "TAPETYPE SECTION"
+The
+.B amanda.conf
+file may define multiple types of tape media and devices.
+The information is entered in a
+.B tapetype
+section, which looks like this in the config file:
+.LP
+.RS
+.EX
+define tapetype \fIname\fP {
+    \fItapetype\-option\fP \fItapetype\-value\fP
+    \fI...\fP
+}
+.EE
+.RE
+.LP
+.I Name
+is the name of this type of tape medium/device.
+It is referenced from the
+.B tapetype
+option in the main part of the config file.
+.LP
+The tapetype options and values are:
+.TP
+.BS comment string
+Default:
+.IR none .
+A comment string describing this set of tape information.
+.TP
+.BS filemark int
+Default:
+.IR "1000 bytes" .
+How large a file mark (tape mark) is, measured in bytes.
+If the size is only known in some linear measurement (e.g.\& inches),
+convert it to bytes using the device density.
+.TP
+.BS length int
+Default:
+.IR "2000 kbytes" .
+How much data will fit on a tape.
+.IP
+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
+.B length
+(but see the
+.B OUTPUT DRIVERS
+section later for exceptions).
+.TP
+.BS blocksize int
+Default:
+.IR "32 kbytes" .
+How much data will be written in each tape record.
+The minimum blocksize value is 32 KBytes.
+The maximum blocksize value is @MAXTAPEBLOCKSIZE@ KBytes.
+The maximum is set during configure with --with-maxtapeblocksize.
+.TP
+.BS file-pad boolean
+Default:
+.IR "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 to the availability
+of this parameter.
+It may also be useful on devices that only support a fixed blocksize.
+.IP
+Note that the last record on the tape probably includes trailing
+null byte padding, which will be passed back to
+.BR gzip ,
+.B compress
+or the restore program.
+Most programs just ignore this (although possibly with a warning).
+.IP
+If this parameter is false, the last record in a file may be shorter
+than the block size.
+The file will contain the same amount of data the dump program generated,
+without trailing null byte padding.
+When read, the same amount of data that was written will be returned.
+.TP
+.BS speed int
+Default:
+.IR "200 bps" .
+How fast the drive will accept data, in bytes per second.
+This parameter is not currently used by Amanda.
+.TP
+.BS lbl-templ string
+A PostScript template file used by
+.B amreport
+to generate labels.
+Several sample files are provided with the Amanda sources in the
+.I example
+directory.
+See the
+.IR amreport (8)
+man page for more information.
+.LP
+In addition to options, another
+.B tapetype
+name may be entered, which makes this
+.B tapetype
+inherit options from another
+.BR tapetype .
+For instance, the only difference between a DLT4000 tape drive using
+Compact\-III tapes and one using Compact\-IV tapes is the length of
+the tape.
+So they could be entered as:
+.LP
+.RS
+.EX
+define tapetype DLT4000\-III {
+    comment "DLT4000 tape drives with Compact\-III tapes"
+    length 12500 mbytes         # 10 Gig tapes with some compression
+    filemark 2000 kbytes
+    speed 1536 kps
+}
+define tapetype DLT4000\-IV {
+    DLT4000\-III
+    comment "DLT4000 tape drives with Compact\-IV tapes"
+    length 25000 mbytes         # 20 Gig tapes with some compression
+}
+.EE
+.RE
+.SH "INTERFACE SECTION"
+The
+.B amanda.conf
+file may define multiple types of network interfaces.
+The information is entered in an
+.B interface
+section, which looks like this:
+.LP
+.RS
+.EX
+define interface \fIname\fP {
+    \fIinterface\-option\fP \fIinterface\-value\fP
+    \fI...\fP
+}
+.EE
+.RE
+.LP
+.I Name
+is the name of this type of network interface.
+It is referenced from the
+.I disklist
+file.
+.LP
+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 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 throttling up to the operating system and network hardware.
+.LP
+The interface options and values are:
+.TP
+.BS comment string
+Default:
+.IR none .
+A comment string describing this set of network information.
+.TP
+.BS use int
+Default:
+.IR "300 Kbps" .
+The speed of the interface in Kbytes per second.
+.LP
+In addition to options, another
+.B interface
+name may be entered, which makes this
+.B interface
+inherit options from another
+.BR interface .
+At the moment, this is of little use.
+.SH "DISKLIST FILE"
+The
+.I disklist
+file determines which disks will be backed up by Amanda.
+The file usually contains one line per disk:
+.LP
+.RS
+.I hostname diskname
+[
+.I diskdevice
+]
+.I dumptype
+[
+.I spindle
+[
+.I interface
+] ]
+.RE
+.LP
+All pair [
+.B hostname diskname
+] must be unique.
+.LP
+Lines starting with # are ignored, as are blank lines.
+The fields have the following meanings:
+.TP
+.I hostname
+The name of the host to be backed up.
+If
+.B diskdevice
+refers to a PC share, this is the host Amanda will
+run the Samba
+.B smbclient
+program on to back up the share.
+.TP
+.I diskname
+The name of the disk (a label).
+In most case, you set your
+.B diskname
+to the
+.B diskdevice
+and you don't set the
+.B diskdevice.
+If you want multiple entry with the same
+.B diskdevice,
+you must set a different
+.B diskname
+for each entry. It's the
+.B diskname
+that you use on command line for any amanda command.
+Look at the example/disklist file for example.
+.TP
+.I diskdevice
+Default: same as diskname.
+The name of the disk device to be backed up.
+It may be a full device name,
+a device name without the
+.I /dev/
+prefix, e.g.\&
+.IR sd0a ,
+or a mount point such as
+.IR /usr .
+.IP
+It may also refer to a PC share by starting the name with two (forward)
+slashes, e.g.\&
+.IR //some-pc/home .
+In this case, the
+.B program
+option in the associated
+.B dumptype
+must be entered as
+.BR GNUTAR .
+It is the combination of the double slash disk name and
+.B program GNUTAR
+in the
+.B dumptype
+that triggers the use of Samba.
+.TP
+.I dumptype
+Refers to a
+.B dumptype
+defined in the
+.B amanda.conf
+file.
+.IR Dumptype s
+specify backup related parameters,
+such as whether to compress the backups,
+whether to record backup results in
+.IR /etc/dumpdates ,
+the disk's relative priority,
+etc.
+.TP
+.I spindle
+Default:
+.IR \-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.
+.TP
+.I interface
+Default:
+.IR local .
+The name of a network interface definition in the
+.B amanda.conf
+file, used to balance network load.
+.LP
+Instead of naming a
+.BR dumptype ,
+it is possible to define one in-line, enclosing
+.B dumptype
+options within curly braces, one per line, just like a
+.B dumptype
+definition in
+.BR amanda.conf .
+Since pre-existing
+.BR dumptype s
+are valid option names, this syntax may be used to customize
+.BR dumptype s
+for particular disks.
+.LP
+A line break
+.B must
+follow the left curly bracket.
+.LP
+For instance, if a
+.B dumptype
+named
+.I normal
+is used for most disks, but use of the holding disk needs to be disabled
+for the file system that holds it, this would work instead of defining
+a new dumptype:
+.RS
+.EX
+\fIhostname diskname\fP [ \fIdiskdevice\fP ] {
+  normal
+  holdingdisk no
+} [ \fIspindle\fP [ \fIinterface\fP ] ]
+.EE
+.RE
+.LP
+.SH "TAPE MANAGEMENT"
+The
+.I 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 operation.
+It contains lines of the form:
+.LP
+.RS
+.I YYYYMMDD label flags
+.RE
+.LP
+Where
+.I YYYYMMDD
+is the date the tape was written,
+.I label
+is a label for the tape as written by
+.B amlabel
+and
+.I flags
+tell Amanda whether the tape may be reused, etc (see
+the
+.B reuse
+options of
+.BR amadmin ).
+.LP
+.B Amdump
+and
+.B 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
+(see the
+.B tapecycle
+option)
+than there are runs in the backup cycle
+(see the
+.B dumpcycle
+option)
+to prevent overwriting a backup image that would be needed to
+do a full recovery.
+.SH "OUTPUT DRIVERS"
+The normal value for the
+.B tapedev
+parameter,
+or for what a tape changer returns,
+is a full path name to a non-rewinding tape device,
+such as
+.I /dev/nst0
+or
+.I /dev/rmt/0mn
+or
+.I /dev/nst0.1
+or whatever conventions the operating system uses.
+Amanda provides additional application level drivers that
+support non-tradition tape simulatation or features.
+To access a specific output driver, set
+.B tapedev
+(or configure your changer to return)
+a string of the form
+.I driver\fR:\fIdriver-info
+where
+.I driver
+is one of the supported drivers and
+.I driver-info
+is optional additional information needed by the driver.
+.LP
+The supported drivers are:
+.TP 10
+.I tape
+This is the default driver.
+The
+.I driver-info
+is the tape device name.
+Entering
+.I /dev/rmt/0mn
+is really a short hand for
+.IR tape:/dev/rmt/0mn .
+.TP
+.I 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 regardless of what you have set in
+.BR labelstr .
+The
+.I driver-info
+field is not used and may be left blank:
+.RS
+.IP
+.BS tapedev null:
+.RE
+.IP
+The
+.I length
+value from the associated
+.B tapetype
+is used to limit the amount of data written.
+When the limit is reached, the driver will simulate end of tape.
+.IP
+NOTE: this driver should only be used for debugging and testing,
+and probably only with the
+.B record
+option set to
+.IR no .
+.TP
+.I rait
+\fIR\fRedundant
+\fIA\fRrray
+of
+\fII\fRnexpensive (?)
+\fIT\fRapes.
+Reads and writes tapes mounted on multiple drives by spreading
+the data across N-1 drives and using the last drive for a checksum.
+See docs/RAIT for more information.
+.IP
+The
+.I driver-info
+field describes the devices to use.
+Curly braces indicate multiple replacements in the string.
+For instance:
+.RS
+.IP
+.BS tapedev rait:/dev/rmt/tps0d{4,5,6}n
+.RE
+.IP
+would use the following devices:
+.RS
+.IP
+/dev/rmt/tps0d4n
+.br
+/dev/rmt/tps0d5n
+.br
+/dev/rmt/tps0d6n
+.RE
+.TP
+.I file
+This driver emulates a tape device with a set of files in a directory.
+The
+.I driver-info
+field must be the name of an existing directory.
+The driver will test for a subdirectory of that named
+.I data
+and return
+.B offline
+until it is present.
+When present, the driver uses two files in the
+.I data
+subdirectory for each tape file.
+One contains the actual data.
+The other contains record length information.
+.IP
+The driver uses a file named
+.I status
+in the
+.B file
+device directory to hold driver status information,
+such as tape position.
+If not present, the driver will create it as though the device is rewound.
+.IP
+The
+.I length
+value from the associated
+.B tapetype
+is used to limit the amount of data written.
+When the limit is reached, the driver will simulate end of tape.
+.IP
+One way to use this driver with a real device such as a CD is to
+create a directory for the
+.B file
+device and one or more other directories
+for the actual data.
+Create a symlink named
+.I data
+in the
+.B file
+directory to one of the data directories.
+Set the
+.B tapetype
+length to whatever the medium will hold.
+.IP
+When Amanda fills the
+.B 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.
+.IP
+To read the CD,
+mount it and create the
+.I data
+symlink in the
+.B file
+device directory.
+.SH AUTHORIZATION
+Amanda processes on the tape server host run as the
+.B dumpuser
+user listed in
+.BR amanda.conf .
+When they connect to a backup client, they do so with an Amanda-specific
+protocol.
+They do not, for instance, use
+.B rsh
+or
+.B ssh
+directly.
+.LP
+On the client side, the
+.B amandad
+daemon validates the connection using one of several methods,
+depending on how it was compiled and on options it is passed:
+.LP
+.IP .rhosts
+Even though Amanda does not use
+.BR rsh ,
+it can use
+.BR .rhosts -style
+authentication and a
+.B .rhosts
+file.
+.IP .amandahosts
+This is essentially the same as
+.B .rhosts
+authentication except a different file, with almost the same format, is used.
+This is the default mechanism built into Amanda.
+.IP
+The format of the
+.B .amandahosts
+file is:
+.RS
+.IP
+.I hostname
+[
+.I username
+]
+.RE
+.IP
+If
+.I username
+is ommitted, it defaults to the user running
+.BR amandad ,
+i.e. the user listed in the
+.B inetd
+or
+.B xinetd
+configuration file.
+.IP Kerberos
+Amanda may use the Kerberos authentication system.
+Further information is in the
+.B docs/KERBEROS
+file that comes with an Amanda distribution.
+.LP
+For Samba access,
+Amanda needs a file on the Samba server (which may
+or may not also be the tape server) named
+.B /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 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:
+.LP
+.EX
+  //some-pc/home       normalpw
+  //another-pc/disk    otheruser%otherpw
+.EE
+.LP
+With clear text passwords, this file should obviously be tightly protected.
+It only needs to be readable by the Amanda user on the Samba server.
+.LP
+Further information is in the
+.B docs/SAMBA
+file that comes with an Amanda distribution.
+.SH HOST & DISK EXPRESSION
+All host and disk arguments to programs are special expression.
+The command apply to all disk that match your arguments.
+This section describe the matcher.
+.LP
+The matcher match by word, each word is a glob expression, word
+are separated by the separator '.' for host and '/' for disk. You
+can anchor the 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
+succeed if all word in your expression match contiguous word in 
+the host or disk.
+.LP
+.EX
+ .   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
+.EE
+.LP
+.LP
+Some examples:
+.LP
+.EX
+  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
+
+.EE
+.SH DATESTAMP EXPRESSION
+A
+.I datestamp
+expression is a range expression where we only match the prefix.
+Leading ^ is removed. Trailing $ force an exact match.
+.LP
+.EX
+  20001212-14  match all dates beginning with 20001212, 20001213 or 20001214
+  20001212-4   same as previous
+  20001212-24  match all dates between 20001212 and 20001224
+  2000121      match all dates that start with 2000121 (20001210-20001219)
+  2            match all dates that start with 2 (20000101-29991231)
+  2000-10      match all dates between 20000101-20101231
+  200010$      match only 200010
+.EE
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amadmin(8),
+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),
+amtoc(8),
+amverify(8),
+amverifyrun(8)
diff --git a/man/amcheck.8.in b/man/amcheck.8.in
new file mode 100644 (file)
index 0000000..0cdc22a
--- /dev/null
@@ -0,0 +1,628 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMCHECK 8
+.SH NAME
+amcheck \- run Amanda self\-checks
+.SH SYNOPSIS
+.B amcheck
+[
+.B \-mwsclt
+]
+[
+.BI \-M address
+]
+.I config
+[
+.I host
+[
+.I disk
+]*
+]*
+.SH DESCRIPTION
+.B Amcheck
+runs a number of self\-checks on both the Amanda tape server host and
+the Amanda client hosts.
+.LP
+On the tape server host,
+.B amcheck
+can go through the same tape checking used at the start of the nightly
+.B amdump
+run to verify the correct tape for the next run is mounted.
+.LP
+.B 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.
+.LP
+You can specify many host/disk expressions, only  disks that
+match an expression will be checked. All disk are checked if no
+expression are given.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH OPTIONS
+.TP
+.B \-s
+Run the tape server local and tape checks
+(same as
+.BR \-lt ).
+.TP
+.B \-c
+Run the client host checks.
+.TP
+.B \-l
+Run the local tests (e.g. permissions) on the server host.
+.TP
+.B \-t
+Run the tape tests on the server host.
+.TP
+.B \-w
+Enables a destructive check for write\-protection on the
+tape (which would otherwise cause the subsequent
+.B 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
+.B \-t
+and is only made if the tape is otherwise correct.
+.TP
+.B \-m
+Nothing is printed, but mail is sent
+if any errors are detected.
+The mail goes to the
+.B mailto
+address specified in the
+.I amanda.conf
+file or the
+.I address
+value if
+.B \-M
+is set.
+.TP
+.B \-a
+Like
+.B \-m
+but the mail is always sent.
+.TP
+.BI \-M address
+Mail the report to
+.I address
+instead of the
+.B mailto
+value from
+.IR amanda.conf .
+Implies
+.BR \-m .
+.LP
+The default is
+.BR \-cs .
+.SH EXAMPLES
+In this example, both the tape server and client tests are run.
+The results are displayed on standard output.
+.LP
+.RS
+.EX
+% amcheck @DEFAULT_CONFIG@
+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
+--------------------------------
+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.2)
+.EE
+.RE
+.LP
+In this example, if the line
+.B mailto csd-amanda
+is in
+.IR amanda.conf ,
+mail will be sent to
+.B csd-amanda
+if the server check returns an error.
+.LP
+.RS
+.EX
+% amcheck \-s \-m @DEFAULT_CONFIG@
+.EE
+.RE
+.SH MESSAGES
+.TP
+fatal slot \fIslot\fP: \fIerror message\fP
+(error)
+The tape changer detected some kind of fatal error
+while trying to load slot
+.IR slot .
+.TP
+slot \fIslot\fP: \fIerror message\fP
+(warning)
+The tape changer detected some kind of non-fatal error
+(e.g. an empty slot was detected)
+while trying to load slot
+.IR slot ,
+or an error was detected trying to read the tape label.
+.TP
+slot \fIslot\fP: date \fIYYYYMMDD\fP label \fIlabel\fP (\fIresult\fP)
+(info)
+Tape
+.I label
+in slot
+.I slot
+was loaded and found to have been last written on
+.IR YYYYMMDD .
+If the tape is new, the date field will be an
+.IR X .
+The
+.I result
+may be one of:
+.RS
+.TP
+exact label match
+This is the expected tape.
+.TP
+no match
+This label does not match the
+.B labelstr
+pattern in
+.IR amanda.conf .
+Tape scanning will continue.
+.TP
+active tape
+This tape is still active and cannot be overwritten.
+Tape scanning will continue.
+.TP
+first labelstr match
+This tape is the first one that matches the
+.B labelstr
+pattern in
+.IR amanda.conf .
+Tape scanning will continue if necessary.
+.TP
+labelstr match
+This tape is the next one that matches the
+.B labelstr
+pattern in
+.IR amanda.conf .
+Tape scanning will continue.
+.RE
+.TP
+ERROR: cannot look up dump user "\fIuser\fP"
+(error)
+Dump user
+.I user
+from
+.I amanda.conf
+could not be found in the system password information.
+.TP
+ERROR: cannot look up my own uid (\fIuid\fP)
+(error)
+User id
+.I uid
+running
+.B amcheck
+could not be found in the system password information.
+.TP
+ERROR: running as user "\fIrunuser\fP" instead of "\fIdumpuser\fP"
+(error)
+.B Amcheck
+should be run as the dump user
+.I dumpuser
+from
+.I amanda.conf
+instead of
+.IR runuser .
+.TP
+ERROR: program dir \fIdirectory\fP: not accessible
+(error)
+The directory Amanda expects to find its auxiliary programs in,
+.IR directory ,
+is not accessible.
+.TP
+ERROR: program \fIprogram\fP: does not exist
+(error)
+Program
+.I program
+needed on the tape server could not be found.
+.TP
+ERROR: program \fIprogram\fP: not a file
+(error)
+Program
+.I program
+needed on the tape server exists but is not a file.
+.TP
+ERROR: program \fIprogram\fP: not executable
+(error)
+Program
+.I program
+needed on the tape server exists but is not executable.
+.TP
+WARNING: program \fIprogram\fP: not setuid-root
+(warning)
+Program
+.I program
+needed on the tape server exists but should be owned by user "root"
+and setuid.
+.TP
+ERROR: \fIXXX\fP dir \fIdirectory\fP: not writable
+(error)
+Directory
+.I directory
+is either not writable,
+i.e. the dump user will not be able to create or remove files,
+or cannot be accessed, perhaps because a parent directory
+does not allow search permission.
+The
+.I XXX
+may be:
+.RS
+.TP
+log
+for the Amanda log directory (see
+.B logdir
+in
+.BR amanda.conf )
+.TP
+oldlog
+for the directory that holds the old log files (see
+.B logdir
+in
+.BR amanda.conf )
+.TP
+info
+for an Amanda database information directory (see
+.B curinfo
+in
+.BR amanda.conf )
+or
+.TP
+index
+for an Amanda index directory (see
+.B indexdir
+in
+.BR amanda.conf )
+.TP
+tapelist
+for the Amanda tapelist directory (see
+.B tapelist
+in
+.BR amanda.conf )
+.RE
+.TP
+NOTE: \fIXXX\fP dir \fIdirectory\fP: does not exist
+(info)
+A database (info) or index directory does not exist or cannot be accessed.
+This might just mean this is a new client or disk,
+but if that is not the case,
+this should be treated as an error.
+.TP
+NOTE: it will be created on the next run
+(info)
+This indicates the info directory listed in the previous message
+will be created on the next run.
+.TP
+ERROR: \fIXXX\fP dir \fIname\fP: not a directory
+(error)
+.B Amcheck
+expected
+.I name
+to be a directory,
+but it is something else (e.g. file).
+.TP
+WARNING: info file \fIfile\fP: does not exist
+(warning)
+File
+.I file
+does not exist in the text format database.
+Since the parent directories do exist,
+the file should already have been created.
+.TP
+ERROR: info file \fIname\fP: not a file
+(error)
+.B Amcheck
+expected
+.I name
+to be a file,
+but it is something else (e.g. file).
+.TP
+ERROR: info file \fIfile\fP: not readable
+(error)
+The text format database file
+.I file
+is not readable.
+.TP
+ERROR: log file \fIfile\fP: not writable
+(error)
+Log file
+.I file
+(file
+.B log
+in
+.B logdir
+from
+.BR amanda.conf )
+is either not writable,
+or cannot be accessed, perhaps because a parent directory
+does not allow search permission.
+.TP
+ERROR: tape list \fItapelist\fP: not writable
+(error)
+Amanda tape list file
+.I tapelist
+(see
+.B tapelist
+in
+.BR amanda.conf )
+is not writable or was not found.
+.TP
+ERROR: tape list \fItapelist\fP: parse error
+(error)
+Amanda tape list file
+.I tapelist
+(see
+.B tapelist
+in
+.BR amanda.conf )
+could not be read or parsed.
+.TP
+WARNING: tapedev is /dev/null, dumps will be thrown away
+(warning)
+The
+.B tapedev
+parameter in
+.B amanda.conf
+is set to
+.B /dev/null
+and Amanda uses that when debugging to throw all the dump images away.
+.TP
+WARNING: hold file \fIfile\fP exists
+(info)
+Hold file
+.I file
+exists and will cause
+.B amdump
+to pause at the beginning until it is removed.
+.TP
+ERROR: holding disk \fIdisk\fP: statfs: \fIerror message\fP
+(error)
+An error was returned from the
+.I statfs
+system call on holding disk
+.I disk
+(maybe because it does not exist).
+.TP
+ERROR: holding disk \fIdisk\fP: not writable
+(error)
+Holding disk
+.IR disk ,
+is not writable,
+probably because the caller does not have write permission
+or a parent directory does not allow search permission.
+.TP
+WARNING: holding disk \fIdisk\fP: available space unknown \fIN\fP KB requested.
+(warning)
+.B Amcheck
+could not determine the amount of available space on holding disk
+.I disk
+to see if there were at least
+.I N
+KBytes available.
+.TP
+WARNING: holding disk \fIdisk\fP: only \fIF\fP KB free (\fIR\fP KB requested).
+(warning)
+.I Amanda.conf
+requested
+.I R
+KBytes of free space on holding disk
+.IR disk ,
+but only
+.I F
+KBytes were available.
+10 MBytes is subtracted for each backup process
+(see the
+.B inparallel
+.I amanda.conf
+option)
+to allow for unexpected overruns.
+.IP
+Note:
+even though this message is listed as a warning, it causes
+.B amcheck
+to exit with a non-zero status.
+.TP
+Holding disk \fIdisk\fP: \fIN\fP KB disk space available, that's plenty.
+(info)
+There was sufficient free space on holding disk
+.IR disk .
+.TP
+WARNING: holding disk \fIdisk\fP: only \fIF\fP KB free, using nothing
+(warning)
+Holding disk
+.I disk
+has
+.I F
+KBytes of free space, but that is not enough for what is requested in
+.IR amanda.conf .
+.TP
+Holding disk \fIdisk\fP: \fIF\fP KB disk space available, using \fIU\fP KB
+(info)
+Holding disk
+.I disk
+has
+.I F
+KBytes of free space and Amanda will be using up to
+.I U
+Kbytes.
+.TP
+WARNING: if a tape changer is not available, runtapes must be set to 1.
+(warning)
+The
+.B runtapes
+.I amanda.conf
+option must be set to 1 if the
+.B tpchanger
+.I amanda.conf
+option is not set.
+.TP
+ERROR: \fIerror message\fP.
+(error)
+An error was detected while initializing the tape changer.
+.TP
+ERROR: \fItape device\fP: \fIerror message\fP.
+(error)
+An error was detected while processing the tape label.
+.TP
+ERROR: cannot overwrite active tape \fIlabel\fP.
+(error)
+Tape
+.I label
+is still active and cannot be used.
+.TP
+ERROR: label \fIlabel\fP doesn't match labelstr "\fIpattern\fP".
+(error)
+The label on tape
+.I label
+does not match the
+.B labelstr
+.I amanda.conf
+option.
+.TP
+(expecting a new tape)
+(info)
+The tape is not OK and a new tape was expected.
+.TP
+(expecting tape \fIlabel\fP or a new tape)
+(info)
+The tape is not OK and either tape
+.I label
+or a new tape was expected.
+.TP
+ERROR: tape \fIlabel\fP label ok, but is not writable.
+(error)
+Tape
+.I label
+is OK, but the write enable test failed.
+.TP
+Tape \fIlabel\fP is writable.
+(info)
+Tape
+.I label
+is OK and the write enable test succeeded.
+.TP
+NOTE: skipping tape-writable test.
+(info)
+The tape write test (see the
+.B \-w
+option) was not enabled.
+.TP
+WARNING: skipping tape test because amdump or amflush seem to be running
+.TP
+WARNING: if they are not, you must run amcleanup
+(warning)
+It looked to
+.B amcheck
+like either
+.B amdump
+or
+.B amflush
+were running because a log file or amdump file exists.
+If they are not running, you probably need to run
+.B amcleanup
+to clear up a previous failure.
+Otherwise, you need to wait until they complete before running
+.BI amcheck .
+.TP
+NOTE: skipping tape checks
+(info)
+The tape tests are being skipped because you used the
+.B \-t
+command line option.
+.TP
+WARNING: \fIcompress\fP is not executable, server-compression and indexing will not work
+(warning)
+Compression program
+.I compress
+is not executable,
+so compression on the tape server host and creating index files will not work.
+.TP
+Tape \fIlabel\fP label ok.
+(info)
+Tape
+.I label
+is OK for the next
+run.
+.TP
+Server check took \fIS\fP seconds.
+(info)
+Reports how long the tape server host checks took.
+.TP
+ERROR: \fIhost\fP: could not resolve hostname
+(error)
+Could not look up client hostname
+.IR host .
+.TP
+Client check: \fIH\fP hosts checked in \fIS\fP seconds, \fIN\fP problems found.
+(info)
+Reports the number of client hosts checked,
+how long it took and the number of errors detected.
+.TP
+WARNING: \fIhost\fP: selfcheck request timed out.  Host down?
+(warning)
+There was no response from
+.I host
+when trying to do the client checks.
+The host might really be down or it might not be configured properly.
+.TP
+ERROR: \fIhost\fP NAK: \fImessage\fP
+(error)
+.I Host
+reported a negative acknowledgment error of
+.I message
+to the status check request.
+.TP
+ERROR: \fIhost\fP NAK: [NAK parse failed]
+(error)
+.B Amcheck
+could not parse the negative acknowledgment error from
+.IR host .
+There might be an Amanda version mismatch between the host running
+.B amcheck
+and
+.IR host .
+.TP
+ERROR: \fIhost\fP [mutual-authentication failed]
+(error)
+Kerberos authentication failed while contacting
+.IR host .
+.TP
+ERROR: \fIhost\fP: \fImessage\fP
+(error)
+Error
+.I message
+was reported by the status check on
+.IR host .
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8),
+amdump(8)
diff --git a/man/amcheckdb.8.in b/man/amcheckdb.8.in
new file mode 100644 (file)
index 0000000..b2f5ee7
--- /dev/null
@@ -0,0 +1,54 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMCHECKDB 8
+.SH NAME
+amcheckdb \- check Amanda database for tape consistency
+.SH SYNOPSIS
+.B amcheckdb
+.I config
+.SH DESCRIPTION
+.B Amcheckdb
+verifies that every tape mentioned in the Amanda database
+is still valid in the
+.I tapelist
+file.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH EXAMPLE
+This shows a normal response:
+.LP
+.RS
+.EX
+# amcheckdb @DEFAULT_CONFIG@
+Ready.
+.EE
+.RE
+.LP
+This shows tape
+.I DMP014
+is still listed in the database but is no longer listed in the
+.I tapelist
+file:
+.LP
+.RS
+.EX
+# amcheckdb @DEFAULT_CONFIG@
+Tape DMP014 missing in @CONFIG_DIR@/@DEFAULT_CONFIG@/tapelist
+Ready.
+.EE
+.RE
+.SH AUTHOR
+Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>
+.SH "SEE ALSO"
+amadmin(8),
+amrmtape(8),
+amanda(8)
diff --git a/man/amcleanup.8.in b/man/amcleanup.8.in
new file mode 100644 (file)
index 0000000..d0c8dba
--- /dev/null
@@ -0,0 +1,73 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMCLEANUP 8
+.SH NAME
+amcleanup \- run the Amanda cleanup process after a failure
+.SH SYNOPSIS
+.B amcleanup
+.I config
+.SH DESCRIPTION
+.B Amcleanup
+generates the
+.I 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
+.B amdump
+program, but if
+.B amdump
+cannot complete for some reason (usually because of a tape server host crash),
+.B amcleanup
+must be run some time later
+(usually during system boot).
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH EXAMPLES
+This example runs the Amanda cleanup process by hand after
+a failure.
+.LP
+.RS
+.EX
+% amcleanup @DEFAULT_CONFIG@
+.EE
+.RE
+.LP
+Putting the following line in a system boot script (e.g.\&
+.IR /etc/rc.local )
+runs the Amanda cleanup process as part of the reboot,
+eliminating the need to run it by hand.
+.LP
+.RS
+.EX
+.ie '@sbindir@'${exec_prefix}/sbin' \{\
+.ie '@exec_prefix@'${prefix}' .ds pr @prefix@/sbin
+.el .ds pr @exec_prefix@/sbin\}
+.el .ds pr @sbindir@
+\*(pr/amcleanup @DEFAULT_CONFIG@
+.EE
+.RE
+.LP
+If nothing needs to be done,
+.B amcleanup
+exits normally with the message:
+.LP
+.RS
+.EX
+amcleanup: no unprocessed logfile to clean up.
+.EE
+.RE
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8),
+amdump(8)
diff --git a/man/amdd.8 b/man/amdd.8
new file mode 100644 (file)
index 0000000..9a88e31
--- /dev/null
@@ -0,0 +1,121 @@
+.\"
+.de CO
+\fB\\$1\fP \fI\\$2\fP
+..
+.TH AMDD 8
+.SH NAME
+amdd \- Amanda version of dd
+.SH SYNOPSIS
+.B amdd
+[
+.B -d
+]
+[
+.B if=\fIinput
+]
+[
+.B of=\fIoutput
+]
+[
+.B bs=\fIblocksize
+]
+[
+.B skip=\fIcount
+]
+[
+.B count=\fIcount
+]
+.SH DESCRIPTION
+.B Amdd
+provides just enough of the standard
+.UX
+.B dd
+command for the needs of Amanda.
+This is handy when doing a full restore and the standard
+.B dd
+program has not yet been found.
+.LP
+.B 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.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+See the
+.B OUTPUT DRIVERS
+section of
+.I amanda(8)
+for more information on the Amanda output drivers.
+.SH OPTIONS
+.de BS
+\fB\\$1\fP\ \fR\\$2\fP
+..
+.TP
+.B \-d
+Turn on debugging output.
+.TP
+.BI \-l length
+Set the output length.
+If the output driver limits the output size, this controls
+when end of tape will be simulated.
+.IP
+.I Length
+may have a multiplier suffix:
+.RS
+.IP
+.BS k 1024\ (Kilobytes)
+.IP
+.BS b 512\ (Blocks)
+.IP
+.BS M 1024*1024\ (Megabytes)
+.RE
+.IP
+The default is no multipler (bytes).
+.TP
+.B if=\fIinput
+Input to
+.BR dd .
+Default is stdin.
+.TP
+.B of=\fIoutput
+Where to send the output of
+.BR dd .
+Default is stdout.
+.TP
+.B bs=\fIblocksize
+Size of each record.
+Input records smaller than this will
+.I not
+be padded.
+Output records will be the same size as the corresponding input record.
+Default is 512 bytes.
+.IP
+.I Blocksize
+may have a multiplier suffix:
+.RS
+.IP
+.BS k 1024\ (Kilobytes)
+.IP
+.BS b 512\ (Blocks)
+.IP
+.BS M 1024*1024\ (Megabytes)
+.RE
+.IP
+The default is no multipler (bytes).
+.TP
+.B count=\fIcount
+Number of records to copy.
+Default is all records until end of file.
+.TP
+.B skip=\fIcount
+Number of records to skip before copying input to output.
+Default is zero.
+.SH AUTHOR
+Marc Mengel <mengel@fnal.gov>
+.br
+John R. Jackson <jrj@purdue.edu>
+.SH "SEE ALSO"
+amanda(8)
diff --git a/man/amdump.8.in b/man/amdump.8.in
new file mode 100644 (file)
index 0000000..3c520e6
--- /dev/null
@@ -0,0 +1,97 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMDUMP 8
+.SH NAME
+amdump \- back up all disks in an Amanda configuration
+.SH SYNOPSIS
+.B amdump
+.I config
+[
+.I host
+[
+.I disk
+]*
+]*
+.SH DESCRIPTION
+.B Amdump
+switches to the appropriate Amanda configuration directory,
+e.g. @CONFIG_DIR@/\fIconfig\fR,
+then attempts to back up every disk specified by the
+.I amanda.conf
+file.
+.B Amdump
+is normally run by
+.BR cron .
+.LP
+You can specify many host/disk expression, only disks that
+match an expression will be dumped. All disk are dumped if no
+expression are given.
+.LP
+If file @CONFIG_DIR@/\fIconfig\fR/hold exists,
+.B amdump
+will wait until it 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,
+.B amdump
+checks for the hold file every minute.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH EXAMPLE
+Here is a typical crontab entry.
+It runs
+.B amdump
+every weeknight at 1 a.m. as user
+.BR bin :
+.LP
+.RS
+.EX
+.ie '@sbindir@'${exec_prefix}/sbin' \{\
+.ie '@exec_prefix@'${prefix}' .ds pr @prefix@/sbin
+.el .ds pr @exec_prefix@/sbin\}
+.el .ds pr @sbindir@
+0 1 * * 1-5 bin \*(pr/amdump @DEFAULT_CONFIG@
+.EE
+.RE
+.LP
+Please see the 
+.IR crontab (5)
+or
+.IR crontab (1)
+manual page for the correct crontab format for your system.
+.SH MESSAGES
+.TP
+amdump: waiting for hold file to be removed
+The "hold" file exists and amdump is waiting for it to be removed
+before starting backups.
+.TP
+amdump: amdump or amflush is already running, or you must run amcleanup
+Amdump detected another amdump or amflush running,
+or the remains of a previous incomplete amdump or amflush run.
+This run is terminated.
+If the problem is caused by the remains of a previous run,
+you must execute
+.IR amcleanup (8)
+and then rerun
+.IR amdump .
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8),
+amcheck(8),
+amcleanup(8),
+amrestore(8),
+amflush(8),
+cron(8)
diff --git a/man/amflush.8.in b/man/amflush.8.in
new file mode 100644 (file)
index 0000000..961918e
--- /dev/null
@@ -0,0 +1,141 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMFLUSH 8
+.SH NAME
+amflush \- flush Amanda backup files from holding disk to tape
+.SH SYNOPSIS
+.B amflush
+[
+.B -b
+] [
+.B -f
+] [
+.B -s
+] [
+.B -D
+.I datestamp
+]*
+.I config
+[
+.I host
+[
+.I disk
+]*
+]*
+.SH DESCRIPTION
+.B Amflush
+writes Amanda backups from the holding disks to tape,
+and updates the Amanda info database and tape list accordingly.
+Backups may stay in a holding disk when something is wrong with the tape
+at the time
+.B amdump
+is run.
+When this happens, the problem must be corrected and
+.B amflush
+run by hand.
+.SH OPTIONS
+.TP
+.B \-b
+Run
+.B amflush
+in batch mode. All datestamp are selected unless specified.
+The flush is started without confirmation.
+.TP
+.B \-f
+Run
+.B amflush
+in foreground.
+.B Amflush
+normally detaches itself from the tty and runs as a background process.
+With the
+.B -f
+option,
+.B amflush
+stays in the foreground.
+This is useful if
+.B amflush
+is run as part of another script that, for example, advances the tape
+after the flush is completed.
+.TP
+.B \-s
+Write log to stdout/stderr instead of the amflush log file. Require the
+.B \-f
+option.
+.TP
+.B \-D datestamp
+specify a  datestamp expression you want to flush, see the 
+"DATASTAMP EXPRESSION" section of
+.IR amanda (8)
+for a description.
+.B -D 20001225-7
+will flush all
+dump from 25 december 2000 to 27 december 2000.
+.LP
+You can specify many host/disk expressions, only disks that
+match an expression will be flushed. All disk are flushed if no
+expression are given. see the "HOST & DISK EXPRESSION" section of
+.IR amanda (8)
+for a description.
+.PP
+.B Amflush
+will look in the holding disks specified by the
+.I amanda.conf
+file in @CONFIG_DIR@/\fIconfig\fR
+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
+.B amdump
+was run, e.g.\&
+.IR 19910215 .
+.PP
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH EXAMPLE
+.B Amflush
+will search for holding areas associated with the
+.I PUCC
+configuration.
+After you select which holding area to flush,
+.B amflush
+writes the data to tape, updates the databases and sends
+a mail report similar to
+.IR amdump (8).
+.LP
+.RS
+.EX
+% amflush @DEFAULT_CONFIG@
+Scanning /amanda-hold...
+  20001113: found Amanda directory.
+  20001114: found Amanda directory.
+
+Multiple Amanda directories, please pick one by letter:
+  A. 20001113
+  B. 20001114
+Select directories to flush [A..B]: [ALL] all
+
+Flushing dumps in 20001113, 20001114,
+today: 20001117
+to tape drive /dev/rmt/0mn.
+Expecting tape DMP014 or a new tape.  (The last dumps were to tape DMP013)
+Are you sure you want to do this? yes
+Running in background, you can log off now.
+You'll get mail when amflush is finished.
+.EE
+.RE
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8),
+amdump(8)
diff --git a/man/amgetconf.8.in b/man/amgetconf.8.in
new file mode 100644 (file)
index 0000000..80237c2
--- /dev/null
@@ -0,0 +1,120 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMGETCONF 8
+.SH NAME
+amgetconf \- look up amanda.conf variables
+.SH SYNOPSIS
+.B amgetconf
+[
+.I config
+]
+.I parameter
+.SH DESCRIPTION
+.B Amgetconf
+looks up parameters in
+.IR amanda.conf ,
+the Amanda configuration file,
+or from the build and runtime environment,
+and returns their corresponding value.
+.LP
+If
+.I config
+is not specified,
+.B amgetconf
+assumes it is being run from the configuration directory and that
+.I amanda.conf
+is present.
+.LP
+If
+.I parameter
+begins with
+.IR build. ,
+the (case insensitive) string following the period
+is a build environment variable.
+Variables without a value (e.g.\&
+.I XFSDUMP
+on a system that does not support that type of file system)
+will not report an error and will return an empty string as the value.
+Flag variables (e.g.\&
+.IR USE_AMANDAHOSTS )
+will return
+.I 1
+if the flag is set or an empty string if it is not.
+.LP
+If
+.I parameter
+begins with
+.IR 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 file is returned.
+.LP
+If
+.I parameter
+begins with
+.IR dbclose. ,
+the string following the period is a program name previously used with
+.IR dbopen. ,
+followed by a colon (:) and the previously opened file name.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH EXAMPLE
+Find out the path to the log file directory:
+.LP
+.RS
+.nf
+% amgetconf @DEFAULT_CONFIG@ logdir
+@CONFIG_DIR@/@DEFAULT_CONFIG@
+.fi
+.RE
+.LP
+Find out the current tape type:
+.LP
+.RS
+.nf
+% amgetconf @DEFAULT_CONFIG@ tapetype
+DLT4000-IV
+.fi
+.RE
+.LP
+Find out the default configuration directory:
+.LP
+.RS
+.nf
+% amgetconf @DEFAULT_CONFIG@ build.CONFIG_DIR
+@CONFIG_DIR@
+.fi
+.RE
+.LP
+Create, use and close a debug file in a script:
+.LP
+.RS
+.nf
+% set debug_file = `amgetconf @DEFAULT_CONFIG@ dbopen.myscript`
+% echo debug information >> $debug_file
+% amgetconf @DEFAULT_CONFIG@ dbclose.myscript:$debug_file
+.fi
+.RE
+.SH MESSAGES
+.TP
+amgetconf: no such parameter "\fIparam\fR"
+Parameter
+.I param
+is not a known keyword
+(e.g. not a valid
+.I amanda.conf
+keyword).
+In this case,
+.B amgetconf
+will write "\fBBUGGY\fR" to stdout as the value.
+.SH "SEE ALSO"
+amanda(8)
diff --git a/man/amlabel.8.in b/man/amlabel.8.in
new file mode 100644 (file)
index 0000000..5c478ae
--- /dev/null
@@ -0,0 +1,143 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMLABEL 8
+.SH NAME
+amlabel \- label an Amanda tape
+.SH SYNOPSIS
+.B amlabel
+[-f]
+.I config label
+[
+.B slot
+.I slot
+]
+.SH DESCRIPTION
+All Amanda tapes must be pre-labeled before they are used.
+Amanda verifies the label in
+.B amdump
+and
+.B amflush
+before writing to make sure the proper tape is loaded.
+.LP
+.B Amlabel
+writes an Amanda label on the tape in the device specified by the
+.I amanda.conf
+file in @CONFIG_DIR@/\fIconfig\fR.
+.I Label
+may be any string that does not contain whitespace and that matches the
+.I amanda.conf
+.B labelstr
+regular expression option.
+It is up to the system administrator to define a naming convention.
+.LP
+.B Amlabel
+appends the new tape to the
+.I tapelist
+file so it will be used by Amanda before it reuses any other
+tapes.
+When you
+.B amlabel
+multiple tapes, they will be used in the
+order you
+.B amlabel
+them.
+.LP
+.B 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
+.B -f
+(force) flag bypasses these verifications.
+.LP
+An optional
+.I slot
+may be specified after the tape label.
+If a tape changer is in use,
+.B amlabel
+will label the tape in the specified slot
+instead of the currently loaded tape.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH EXAMPLE
+Write an Amanda label with the string "DMP000" on
+the tape loaded in the device named in the
+.B tapedev
+option in @CONFIG_DIR@/@DEFAULT_CONFIG@/amanda.conf:
+.LP
+.RS
+.EX
+% amlabel @DEFAULT_CONFIG@ DMP000
+.EE
+.RE
+.LP
+Label the tape in slot 3 of the currently configured tape changer
+with the string "DMP003":
+.LP
+.RS
+.EX
+% amlabel @DEFAULT_CONFIG@ DMP003 slot 3
+.EE
+.RE
+.SH MESSAGES
+.TP
+label \fIlabel\fR doesn't match labelstr "\fIstr\fR"
+Label
+.I label
+on the command line does not match the
+.I labelstr
+regular expression
+.I str
+from
+.IR amanda.conf .
+.TP
+label \fIlabel\fR already on a tape
+Label
+.I label
+is already listed as an active Amanda tape.
+.TP
+no tpchanger specified in "\fIpath\fR", so slot command invalid
+The command line has the
+.B slot
+parameter but the
+.I amanda.conf
+file in
+.I path
+does not have a tape changer configured.
+.TP
+reading label \fIlabel\fR, tape is in another amanda configuration
+This tape appears to be a valid Amanda tape,
+but label does not match
+.B labelstr
+for this configuration so it is probably part of a different
+Amanda configuration.
+.TP
+reading label \fIlabel\fR, tape is active
+Tape
+.I label
+appears to already be part of this Amanda configuration
+and active, i.e. has valid data on it.
+.TP
+no label found, are you sure \fItape\fR is non-rewinding?
+While checking that the label was written correctly,
+.I amlabel
+got an error that might be caused by mis-configuring Amanda
+with a rewinding tape device name
+instead of a non-rewinding device name for
+.IR tape.
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8)
+amdump(8)
+amflush(8)
diff --git a/man/ammt.8 b/man/ammt.8
new file mode 100644 (file)
index 0000000..d6aec29
--- /dev/null
@@ -0,0 +1,141 @@
+.\"
+.de CO
+\fB\\$1\fP \fI\\$2\fP
+..
+.TH AMMT 8
+.SH NAME
+ammt \- Amanda version of mt
+.SH SYNOPSIS
+.B ammt
+[
+.B -d
+]
+[
+.B -f|-t
+.I device
+]
+.B command
+[
+.I count
+]
+.SH DESCRIPTION
+.B Ammt
+provides just enough of the standard
+.UX
+.B mt
+command for the needs of Amanda.
+This is handy when doing a full restore and the standard
+.B mt
+program has not yet been found.
+.LP
+.B Ammt
+also provides access to the Amanda output drivers that support
+various tape simulations.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+See the
+.B OUTPUT DRIVERS
+section of
+.I amanda(8)
+for more information on the Amanda output drivers.
+.SH OPTIONS
+.TP
+.B \-d
+Turn on debugging output.
+.TP
+.BI \-f \ device
+Access tape device
+.IR device .
+If not specified, the
+.B TAPE
+environment variable is used.
+.TP
+.BI \-t \ device
+Same as
+.BR -f .
+.TP
+.BI command \ count
+Which command to issue, and an optional count of operations.
+.SH COMMANDS
+Each command may be abbreviated to whatever length makes it unique.
+.TP
+.BI eof|weof \ count
+Write
+.I count
+(default: 1)
+end of file marks (tapemarks).
+.TP
+.BI fsf \ count
+Skip forward
+.I count
+(default: 1)
+files.
+.TP
+.BI bsf \ count
+Skip backward
+.I count
+(default: 1)
+files.
+.TP
+.BI asf \ count
+Position to file number
+.I count
+(default: 0)
+where zero is beginning of tape.
+This is the same as a
+.B rewind
+followed by a
+.B fsf
+.IR count .
+.TP
+.B rewind
+Rewind to beginning of tape.
+.TP
+.B offline|rewoffl
+Rewind to beginning of tape and unload the tape from the drive.
+.TP
+.BI status
+Report status information about the drive.
+Which data reported,
+and what it means,
+depends on the underlying operating system,
+and may include:
+.RS
+.TP
+ONLINE
+Indicates the drive is online and ready.
+.TP
+OFFLINE
+Indicates the drive is offline or not ready.
+.TP
+BOT
+Indicates the drive is at beginning of tape.
+.TP
+EOT
+Indicates the drive is at end of tape.
+.TP
+PROTECTED
+Indicates the tape is write protected.
+.TP
+ds
+Device status.
+.TP
+er
+Error register.
+.TP
+fileno
+Current tape file number.
+.TP
+blkno
+Current tape block number file.
+.RE
+.IP
+NOTE: many systems only report good data when a tape is in the drive and ready.
+.SH AUTHOR
+Marc Mengel <mengel@fnal.gov>
+.br
+John R. Jackson <jrj@purdue.edu>
+.SH "SEE ALSO"
+amanda(8)
diff --git a/man/amoverview.8.in b/man/amoverview.8.in
new file mode 100644 (file)
index 0000000..fea91bc
--- /dev/null
@@ -0,0 +1,112 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.de OP
+\fB\\$1\fP \fI\\$2\fP
+..
+.TH AMOVERVIEW 8
+.SH NAME
+amoverview \- display file systems processed by Amanda over time
+.SH SYNOPSIS
+.B amoverview
+[[
+.B -config
+]
+.I config
+] [
+.OP -hostwidth width
+] [
+.OP -diskwidth width
+] [
+.B -verbose
+]
+.SH DESCRIPTION
+.B Amoverview
+displays a chart showing hosts and file systems processed by Amanda
+along with the backup level performed each day.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH OPTIONS
+.TP
+.OP -config config
+Use configuration
+.I config
+instead of @DEFAULT_CONFIG@.
+.TP
+.OP -hostwidth width
+Set
+.B host
+field column width to
+.I width
+characters instead of eight.
+.TP
+.OP -diskwidth width
+Set
+.B disk
+field column width to
+.I width
+characters instead of 20.
+.TP
+.B -verbose
+.B Amoverview
+can take a long while on large systems.
+This option reports intermediate steps while it is working.
+.SH RESULTS
+.B amoverview
+is a summary of the output of "
+.B amadmin <config> find
+".
+When the last column of 
+.B amadmin find
+contains anything other than "OK",
+amoverview translates this into 'E' for that day.
+
+A number indicates the level of backup and it succeeded.
+An "E" indicates an error for that day.
+You get an 'E' for all errors, like failed to connect, datatimeout,
+computer crashed, etc, but also for failing to write to tape.
+
+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 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 successfull flush afterwards
+giving maybe "EE0".  (Only the latest 2 characters are printed).
+.SH EXAMPLE
+This shows the
+.I /home
+file system on
+.I host2
+was backed up at level 3 on the 8th, 9th and 10th of December,
+had a full backup on the 11th,
+a level 1 on the 12th and a level 2 on the 13th.
+.LP
+.RS
+.EX
+# amoverview
+                         date 12 12 12 12 12 12
+host     disk                 08 09 10 11 12 13
+host1    /                     0  1  1  1  1  1
+host1    /var                  0  1  1  1  1  1
+host2    /                     1  1  1  1  1  0
+host2    /home                 3  3  3  0  1  2
+host2    /opt                  1  1  1  1  1  1
+host2    /var                  1  1  0  1  1  1
+.EE
+.RE
+.SH "SEE ALSO"
+amadmin(8),
+amanda(8)
diff --git a/man/amplot.8 b/man/amplot.8
new file mode 100644 (file)
index 0000000..15deaba
--- /dev/null
@@ -0,0 +1,174 @@
+.TH AMPLOT 8
+.UC 4
+.SH NAME
+amplot \- visualize the behavior of Amanda
+.SH SYNOPSIS
+.B amplot
+[
+.B -b
+]
+[
+.B -c
+]
+[
+.B -e
+]
+[
+.B -g
+]
+[
+.B -l
+]
+[
+.B -p
+]
+[
+.B -t
+.I T
+]
+.I amdump_files
+.br
+.SH DESCRIPTION
+.B Amplot
+reads an
+.B amdump
+output file that Amanda generates each run (e.g.
+.IR 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.
+.B Amplot
+also prints out
+.B amdump
+lines that it either does not
+understand or knows to be warning or error lines
+and a summary of the start, end and total time for each backup image.
+.LP
+.B Amplot
+is a shell script that executes an
+.B awk
+program
+.IR \fR(\fPamplot.awk )
+to scan the
+.B amdump
+output file.
+It then executes a
+.B gnuplot
+program
+.IR \fR(\fPamplot.g )
+to generate the graph.
+The
+.B awk
+program is written in an enhanced version of awk,
+such as GNU awk
+.B \fR(\fPgawk
+version 2.15 or later) or
+.BR nawk .
+.LP
+During execution,
+.B amplot
+generates a few temporary files that
+.B gnuplot
+uses.
+These files are deleted at the end of execution.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH OPTIONS
+.TP
+.B -b
+Generate b/w postscript file (need
+.BR -p ).
+.TP
+.B -c
+Compress
+.I amdump_files
+after plotting.
+.TP
+.B -e
+Extend the X (time) axis if needed.
+.TP
+.B -g
+Direct
+.I gnuplot
+output directly to the X11 display (default).
+.TP
+.B -p
+Direct postscript output to file
+.B \fIYYYYMMDD\fP.ps
+(opposite of
+.BR -g ).
+.TP
+.B -l
+Generate landscape oriented output (need
+.BR -p ).
+.TP
+.B "-t \fIT\fR"
+Set the right edge of the plot to be
+.I T
+hours.
+.LP
+The
+.I amdump_files
+may be in various compressed formats
+.BR \fR(\fPcompress ,
+.BR gzip ,
+.BR pact ,
+.BR compact ).
+.SH INTERPRETATION
+The figure is divided into a number of regions.
+There are titles on the top that show important statistical information
+about the configuration and from this execution of
+.BR amdump .
+In the figure, the X axis is time, with 0 being the moment
+.B amdump
+was started.
+The Y axis is divided into 5 regions:
+.IP
+.I QUEUES:
+How many backups have not been started,
+how many are waiting on space in the holding disk
+and how many have been transferred successfully to tape.
+.IP
+.I %BANDWIDTH:
+Percentage of allowed network bandwidth in use.
+.IP
+.I HOLDING DISK:
+The higher line depicts space allocated on the holding disk to
+backups in progress and completed backups waiting to be written to tape.
+The lower line depicts the fraction of the holding disk containing completed
+backups waiting to be written to tape including the file currently being
+written to tape.
+The scale is percentage of the holding disk.
+.IP
+.I TAPE:
+Tape drive usage.
+.IP
+.I %DUMPERS:
+Percentage of active dumpers.
+.LP
+The idle period at the left of the graph is time
+.B amdump
+is asking the machines how much data they are going to dump.
+This process can take a while if hosts are down
+or it takes them a long time to generate estimates.
+.SH AUTHOR
+Olafur Gudmundsson ogud@tis.com
+.br
+Trusted Information Systems
+.br
+formerly at University of Maryland, College Park
+.SH BUGS
+Reports lines it does not recognize, mainly error cases but some are
+legitimate lines the program needs to be taught about.
+.SH SEE ALSO
+amanda(8),
+amdump(8),
+gawk(1),
+nawk(1),
+awk(1),
+gnuplot(1),
+sh(1),
+compress(1),
+gzip(1)
diff --git a/man/amrecover.8.in b/man/amrecover.8.in
new file mode 100644 (file)
index 0000000..c962b46
--- /dev/null
@@ -0,0 +1,487 @@
+.TH AMRECOVER 8 "29 November 1996" "Alan M. McIvor" "AMANDA INDEX" \" -*- nroff -*-
+.de CP
+.ie '\\$3'' \\fB\\$1\\fP \\fI\\$2\\fP
+.el .ie '\\$2'' \\fB\\$1\\fP [ \\fI\\$3\\fP ]
+.el \\fB\\$1\\fP \\fI\\$2\\fP [ \\fI\\$3\\fP ]
+..
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.SH NAME
+amrecover \- Amanda index database browser
+.SH SYNOPSIS
+.B amrecover
+[
+[
+.B \-C
+]
+.I config
+]
+[
+.B \-s
+.I index-server
+]
+[
+.B \-t
+.I tape-server
+]
+[
+.B \-d
+.I tape-device
+]
+.SH DESCRIPTION
+.B Amrecover
+browses the database of Amanda index files to determine which tapes
+contain files to recover.  Furthermore, it is able to recover files.
+.LP
+In order to restore files in place, you must invoke
+.BR amrecover
+from the root of the backed up filesystem, or use
+.BR 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.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH OPTIONS
+.TP
+.CP "[ -C ]" config
+Amanda configuration
+(default: @DEFAULT_CONFIG@).
+.TP
+.CP -s index-server
+Host that runs the index daemon
+(default: @DEFAULT_SERVER@).
+.TP
+.CP -t tape-server
+Host that runs the tape server daemon
+(default: @DEFAULT_TAPE_SERVER@).
+.TP
+.CP -d tape-device
+Tape device to use on the tape server host
+(default: @DEFAULT_TAPE_DEVICE@).
+.SH COMMANDS
+.B Amrecover
+connects to the index server and then presents a command line prompt.
+Usage is similar to an ftp client.
+The GNU readline library is used to provide command line history and editing
+if it was built in to
+.BR amrecover .
+.LP
+The purpose of browsing the database is to build up a
+.I restore list
+of files to be extracted from the backup system.
+The following commands are available:
+.TP
+.CP sethost hostname
+Specifies which host to look at backup files for
+(default: the local host).
+.TP
+.CP setdate YYYY-MM-DD
+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.
+.IP
+For example, if:
+.LP
+.RS
+.RS
+.nf
+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
+.fi
+.RE
+.RE
+.IP
+then if 1997-07-08 is the requested date,
+files from the following days would be used:
+.LP
+.RS
+.RS
+.nf
+1997-07-08 (the latest level 2 backup)
+1997-07-05 (the latest level 1 backup)
+1997-07-01 (the latest level 0 backup)
+.fi
+.RE
+.RE
+.IP
+Only the most recent version of a file will be presented.
+.IP
+The following abbreviated date specifications are accepted:
+.RS
+.RS
+.TP
+.I --MM-DD
+dates in the current year
+.TP
+.I ---DD
+dates in the current month of the current year
+.RE
+.RE
+.TP
+.CP setdisk diskname mountpoint
+Specifies which disk to consider
+(default: the disk holding the working directory where
+.B amrecover
+is started).
+It can only be set after the host is set with
+.BR sethost .
+.I Diskname
+is the device name specified in the
+.I amanda.conf
+or
+.I disklist
+configuration file.
+The disk must be local to the host.
+If
+.I mountpoint
+is not specified, all pathnames will be relative to the (unknown)
+mount point instead of full pathnames.
+.TP
+.CP listdisk [diskdevice]
+List all
+.B diskname
+.TP
+.CP 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 @DEFAULT_TAPE_SERVER@, 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
+.I 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.
+.IP
+If you want amrecover to use your changer, the 
+.I tapedev
+must be equal to the amrecover_changer setting on the server.
+.IP
+If you need to change the protocol (tape:, rait:, file:, null:) then you
+must specify the hostname.
+.LP
+.RS
+.RS
+.nf
+settape @DEFAULT_TAPE_SERVER@:file:/file1
+.fi
+.RE
+.RE
+.IP
+You can change the tape device when amrecover ask you to load the tape:
+.LP
+.RS
+.RS
+.nf
+Load tape DMP014 now
+Continue? [Y/n/t]: t
+Tape device: server2:/dev/nst2
+Continue? [Y/n/t]: Y
+Using tape /dev/nst2 from server server2.
+.fi
+.RE
+.RE
+.IP
+.TP
+.CP setmode mode
+Set the extraction mode for Samba shares.
+If
+.I mode
+is
+.BR smb ,
+shares are sent to the Samba server
+to be restored back onto the PC.
+If
+.I mode
+is
+.BR tar ,
+they are extracted on the local machine the same way tar volumes are extracted.
+.TP
+.CP mode
+Displays the extracting mode for Samba shares.
+.TP
+.CP history
+Show the backup history of the current host and disk.
+Dates, levels, tapes and file position on tape of each backup are displayed.
+.TP
+.CP pwd
+Display the name of the current backup working directory.
+.TP
+.CP cd dir
+Change the backup working directory to
+.I dir.
+If the mount point was specified with
+.BR setdisk ,
+this can be a full pathname or it can be
+relative to the current backup working directory.
+If the mount point was not specified,
+paths are relative to the mount point if they start with "/",
+otherwise they are relative to the current backup working directory.
+The
+.I dir
+can be a shell style wildcards.
+.TP
+.CP cdx dir
+Like the
+.B cd
+command but allow regular expression.
+.TP
+.CP lpwd
+Display the
+.B amrecover
+working directory.
+Files will be restored under this directory,
+relative to the backed up filesystem.
+.TP
+.CP lcd path
+Change the
+.B amrecover
+working directory to
+.IR path .
+.TP
+.CP ls
+List the contents of the current backup working directory.
+See the description of the
+.B setdate
+command for how the view of the
+directory is built up.
+The backup date is shown for each file.
+.TP
+.CP add item1 "item2 ..."
+Add the specified files or directories to the restore list.
+Each item may have shell style wildcards.
+.TP
+.CP addx item1 "item2 ..."
+Add the specified files or directories to the restore list.
+Each item may be a regular expression.
+.TP
+.CP delete item1 "item2 ..."
+Delete the specified files or directories from the restore list.
+Each item may have shell style wildcards.
+.TP
+.CP deletex item1 "item2 ..."
+Delete the specified files or directories from the restore list.
+Each item may be a regular expression.
+.TP
+.CP 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
+.BR amrestore .
+.TP
+.CP clear
+Clear the restore list.
+.TP
+.CP quit
+Close the connection to the index server and exit.
+.TP
+.CP exit
+Close the connection to the index server and exit.
+.TP
+.CP extract
+Start the extract sequence (see the examples below).  Make sure the
+local working directory is the root of the backed up filesystem, or
+another directory that will behave like that.  Use
+.BR lpwd
+to display the local working directory, and
+.BR lcd
+to change it.
+.TP
+.CP help
+Display a brief list of these commands.
+.SH EXAMPLES
+The following shows the recovery of an old
+.I syslog
+file.
+.LP
+.RS
+.EX
+# cd /var/log
+# ls -l syslog.7
+syslog.7: No such file or directory
+# amrecover
+AMRECOVER Version 2.4.2. Contacting server on @DEFAULT_SERVER@ ...
+220 @DEFAULT_SERVER@ 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 @DEFAULT_CONFIG@.
+200 Dump host set to this-host.some.org.
+$CWD '/var/log' is on disk '/var' mounted at '/var'.
+200 Disk set to /var.
+/var/log
+WARNING: not on root of selected filesystem, check man-page!
+amrecover> ls
+1997-12-09 daemon.log
+1997-12-09 syslog
+1997-12-08 authlog
+1997-12-08 sysidconfig.log
+1997-12-08 syslog.0
+1997-12-08 syslog.1
+1997-12-08 syslog.2
+1997-12-08 syslog.3
+1997-12-08 syslog.4
+1997-12-08 syslog.5
+1997-12-08 syslog.6
+1997-12-08 syslog.7
+amrecover> add syslog.7
+Added /log/syslog.7
+amrecover> lpwd
+/var/log
+amrecover> lcd ..
+/var
+amrecover> extract
+
+Extracting files using tape drive @DEFAULT_TAPE_DEVICE@ on host @DEFAULT_TAPE_SERVER@
+
+The following tapes are needed: DMP014
+
+Restoring files into directory /var
+Continue? [Y/n]: y
+
+Load tape DMP014 now
+Continue? [Y/n/t]: y
+set owner/mode for '.'? [yn] n
+amrecover> quit
+200 Good bye.
+# ls -l syslog.7
+total 26
+-rw-r--r--   1 root     other      12678 Oct 14 16:36 syslog.7
+.EE
+.RE
+.LP
+If you do not want to overwrite existing files,
+create a subdirectory to run
+.B amrecover
+from and then move the restored files afterward.
+.LP
+.RS
+.EX
+# cd /var
+# (umask 077 ; mkdir .restore)
+# cd .restore
+# amrecover
+AMRECOVER Version 2.4.2. Contacting server on @DEFAULT_SERVER@ ...
+\&...
+amrecover> cd log
+/var/log
+amrecover> ls
+\&...
+amrecover> add syslog.7
+Added /log/syslog.7
+amrecover> lpwd
+/var/.restore
+amrecover> extract
+
+Extracting files using tape drive @DEFAULT_TAPE_DEVICE@ on host @DEFAULT_TAPE_SERVER@
+\&...
+amrecover> quit
+200 Good bye.
+# mv -i log/syslog.7 ../log/syslog.7-restored
+# cd ..
+# rm -fr .restore
+.EE
+.RE
+.LP
+If you need to run
+.B amrestore
+by hand instead of letting
+.B amrecover
+control it,
+use the
+.B list
+command after browsing to display the needed tapes.
+.LP
+.RS
+.EX
+# cd /var/log
+# amrecover
+AMRECOVER Version 2.4.2. Contacting server on @DEFAULT_SERVER@ ...
+\&...
+amrecover> ls
+\&...
+amrecover> add syslog syslog.6 syslog.7
+Added /log/syslog
+Added /log/syslog.6
+Added /log/syslog.7
+amrecover> list
+TAPE DMP014 LEVEL 0 DATE 1997-12-08
+        /log/syslog.7
+        /log/syslog.6
+TAPE DMP015 LEVEL 1 DATE 1997-12-09
+        /log/syslog
+amrecover> quit
+.EE
+.RE
+.LP
+The
+.B history
+command shows each tape that has a backup of the
+current disk along with the date of the backup,
+the level,
+the tape label
+and the file position on the tape.
+All active tapes are listed, not just back to
+the most recent full dump.
+.LP
+Tape file position zero is a label.
+The first backup image is in file position one.
+.LP
+.RS
+.EX
+# cd /var/log
+# amrecover
+AMRECOVER Version 2.4.2. Contacting server on @DEFAULT_SERVER@ ...
+\&...
+amrecover> history
+200- Dump history for config "@DEFAULT_CONFIG@" host "this-host.some.org" disk "/var"
+201- 1997-12-09 1 DMP015 9
+201- 1997-12-08 1 DMP014 11
+201- 1997-12-07 0 DMP013 22
+201- 1997-12-06 1 DMP012 16
+201- 1997-12-05 1 DMP011 9
+201- 1997-12-04 0 DMP010 11
+201- 1997-12-03 1 DMP009 7
+201- 1997-12-02 1 DMP008 7
+201- 1997-12-01 1 DMP007 9
+201- 1997-11-30 1 DMP006 6
+\&...
+amrecover> quit
+.EE
+.RE
+.SH ENVIRONMENT
+.LP
+.B PAGER
+.RS
+The 
+.B ls
+and 
+.B list
+commands will use $PAGER to display the file lists.
+Defaults to
+.I more
+if PAGER is not set.
+.RE
+.SH AUTHOR
+Alan M. McIvor <alan@kauri.auck.irl.cri.nz>
+.SH "SEE ALSO"
+amanda(8),
+amrestore(8),
+readline(3)
diff --git a/man/amreport.8.in b/man/amreport.8.in
new file mode 100644 (file)
index 0000000..f319e81
--- /dev/null
@@ -0,0 +1,131 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.de OP
+\fB\\$1\fP \fI\\$2\fP
+..
+.TH AMREPORT 1
+.SH NAME
+amreport \- generate a formatted output of statistics for an Amanda run
+.SH SYNOPSIS
+.B amreport
+[
+.I config
+] [
+.B -l
+.I logfile
+] [
+.B -f
+.I outputfile
+] [
+.B -p
+.I postscriptfile
+] 
+.SH DESCRIPTION
+.B Amreport
+generates a summary report of an
+.IR amanda (8)
+backup run.
+If no configuration name is specified, amanda.conf is
+read from the current directory.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH OPTIONS
+.TP
+.I config
+Name of the configuration to process.
+.TP
+.OP -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:
+.LP
+.RS
+.RS
+\fIlogdir\fP/log
+.RE  
+.RE  
+.IP  
+where
+.I logdir
+is the log directory defined in amanda.conf.
+.TP
+.OP -f outputfile
+Normally,
+.B amreport
+sends the report via e-mail to the
+.I mailto
+user as defined in the amanda.conf file.
+If
+.I outputfile
+is specified, then the report is put in
+.IR outputfile .
+.TP
+.OP -p postscriptfile
+Send the postscript output to the file
+.I postscriptfile
+instead of to the
+.IR lpr (1)
+command.
+This option has an effect only if the
+.I lbl-templ
+directive is specified in amanda.conf.
+.SH LABEL PRINTING
+.LP
+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.
+.LP
+The information printed varies slightly between label templates
+due to size constraints.
+Labels contain one line for each host/file-system
+pair and may also contain the file number on the tape,
+the level of the dump,
+the original size of the dump
+and the size of the (possibly compressed) tape file.
+.LP
+Add the
+.I lbl-templ
+parameter to the tapetype definition in amanda.conf to enable labels.
+If you don't add this line to your
+tapetype definition,
+.B amreport
+will not print tape labels.
+.LP
+You may use the
+.I printer
+keyword in amanda.conf to print to other than the system default printer.
+.LP
+.SH TEMPLATES
+.sp
+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.
+.LP
+.RS
+.RS
+.nf
+* ExaByte 8mm tapes
+* DAT 4mm tapes
+* DLT tapes
+* 3-ring binder
+.fi
+.RE
+.RE
+.LP
+The 3-ring binder type is the most generic.
+It may be used to make a hardcopy log of the tapes.
+.SH "SEE ALSO"
+amanda(8),
+amflush(8)
diff --git a/man/amrestore.8 b/man/amrestore.8
new file mode 100644 (file)
index 0000000..a51961f
--- /dev/null
@@ -0,0 +1,321 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMRESTORE 8
+.SH NAME
+amrestore \- extract backup images from an Amanda tape
+.SH SYNOPSIS
+.B amrestore
+[
+.B \-r
+|
+.B \-c
+|
+.B \-C
+]
+[
+.B \-b
+.I blocksize
+]
+[
+.B \-f
+.I fileno
+]
+[
+.B \-l
+.I label
+]
+[
+.B \-p
+]
+[
+.B \-h
+]
+.I tapedevice
+|
+.I holdingfile
+[
+.I hostname
+[
+.I diskname
+[
+.I datestamp
+[
+.I hostname
+[
+.I diskname
+[
+.I datestamp
+\&...
+]]]]]]
+.SH DESCRIPTION
+.B Amrestore
+extracts backup images from the tape mounted on
+.I tapedevice
+or from the holding disk file
+.I holdingfile
+that match
+.IR hostname ,
+.I diskname
+and
+.I datestamp
+patterns given on the command line.
+The tape or holding file must be in a format written by the
+.B amdump
+or
+.B amflush
+program.
+.LP
+If
+.I diskname
+is not specified, all backups on the tape for the previous
+.I hostname
+are candidates.
+If
+.I datestamp
+is not specified, all backups on the tape for the previous
+.I hostname
+and
+.I diskname
+are candidates.
+If no
+.IR hostname ,
+.I diskname
+or
+.I datestamp
+are specified, every backup on the tape is a candidate.
+.LP
+.I Hostname
+and
+.I diskname
+are special expression descibe in the "HOST & DISK EXPRESSION" section
+of
+.IR amanda (8).
+.I Datestamp
+are special expression describe in the "DATESTAMP EXPRESSION" section
+of
+.IR amanda (8).
+For example, if
+.I diskname
+is "rz[23]a", it would match disks
+.B rz2a
+and
+.BR rz3a .
+.LP
+.I Datestamp
+is useful if
+.B amflush
+writes multiple backup runs to a single tape.
+.PP
+Unless
+.B \-p
+is used,
+candidate backup images are extracted to files
+in the current directory named:
+.LP
+.RS
+.I hostname.diskname.datestamp.dumplevel
+.RE
+.PP
+Amrestore doesn't use a changer, it restore from the tape already loaded
+in the
+.I tapedevice.
+.SH OPTIONS
+.TP
+.B \-b
+Set the blocksize used to read the tape or holding file.
+All holding files must be read with a blocksize of 32 KBytes.
+.B Amrestore
+should normally be able to determine the blocksize for tapes
+on its own and not need this parameter.
+.IP
+The default is 32 KBytes.
+.TP
+.B \-f
+Do a rewind followed by a fsf <fileno> before trying to restore an image.
+.TP
+.B \-l
+Check if we restoring from the tape with the right
+.I label
+.TP
+.B \-p
+Pipe output.
+The first matching backup image is sent to standard output,
+which is normally a pipe to
+.B restore
+or
+.BR tar ,
+then
+.B amrestore
+quits.
+It may be run again to continue selecting backups to process.
+Make sure you specify the no-rewind
+.I tapedevice
+when doing this.
+.IP
+Note:
+.B restore
+may report "short read" errors when reading from a pipe.
+Most versions of
+.B restore
+support a blocking factor option to let you set the read block size,
+and you should set it to 2.
+See the example below.
+.TP
+.B \-c
+Compress output using the fastest method the compression program provides.
+.B Amrestore
+normally writes output files in a format understood by
+.B restore
+or
+.BR tar ,
+even if the backups on the tape are compressed.
+With the
+.B \-c
+or
+.B \-C
+option,
+.B amrestore
+writes all files in compressed format,
+even if the backups on the tape are not compressed.
+Output file names will have a
+.I .Z
+or
+.I .gz
+extension depending on whether
+.B compress
+or
+.B gzip
+is the preferred compression program.
+This option is useful when the current directory disk is small.
+.TP
+.B \-C
+Compress output using the best method the compression program provides
+(may be very CPU intensive).
+See the notes above about the
+.B \-c
+option.
+.TP
+.B \-r
+Raw output.
+Backup images are output exactly as they are on the tape,
+including the
+.B amdump
+headers.
+Output file names will have a
+.I .RAW
+extension.
+This option is only useful for debugging and other strange circumstances.
+.TP
+.B \-h
+Header output.
+The tape header block is output at the beginning of each file.
+This is like
+.B \-r
+except
+.B \-c
+or
+.B \-C
+may also be used to compress the result.
+.B Amrecover
+uses the header to determine the restore program to use.
+.LP
+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.
+.SH EXAMPLES
+The following does an interactive restore of disk
+.I rz3g
+from host
+.IR seine ,
+to restore particular files.
+Note the use of the
+.B b
+option to
+.BR restore ,
+which causes it to read in units of two 512-byte blocks (1 Kbyte)
+at a time.
+This helps keep it from complaining about short reads.
+.LP
+.RS
+.EX
+% amrestore \-p /dev/nrmt9 seine rz3g | restore \-ivbf 2 \-
+.EE
+.RE
+.LP
+The next example extracts all backup images for host
+.IR seine .
+This is the usual way to extract all data for a host after a disk crash.
+.LP
+.RS
+.EX
+% amrestore /dev/nrmt9 seine
+.EE
+.RE
+.LP
+If the backup datestamp in the above example is
+.I 19910125
+and
+.I seine
+has level 0 backups of disks
+.I rz1a
+and
+.I rz1g
+on the tape,
+these files will be created in the current directory:
+.LP
+.RS
+.EX
+seine.rz1a.19910125.0
+seine.rz1g.19910125.0
+.EE
+.RE
+.LP
+You may also use
+.B amrestore
+to extract a backup image from a holding disk
+file that has not yet been flushed to tape:
+.LP
+.RS
+.EX
+% amrestore \-p /amanda/20001119/seine.rz1a.2 | restore \-ivbf 2 \-
+.EE
+.RE
+.LP
+.B Amrestore
+may be used to generate a listing of images on a tape:
+.LP
+.RS
+.EX
+% mt -f /dev/nrmt9 rewind
+% amrestore \-p /dev/nrmt9 no-such-host > /dev/null
+.EE
+.RE
+.LP
+This asks
+.B amrestore
+to find images for host
+.BR no-such-host .
+It will not find any entries that match, but along the way will report
+each image it skips.
+.SH CAVEATS
+.LP
+GNU tar must be used to restore files from backup images created with
+the GNUTAR dumptype.
+Vendor tar programs sometimes fail to read GNU tar images.
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8),
+amdump(8),
+amflush(8),
+tar(1)
+restore(8)
diff --git a/man/amrmtape.8.in b/man/amrmtape.8.in
new file mode 100644 (file)
index 0000000..a4a37fa
--- /dev/null
@@ -0,0 +1,73 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMRMTAPE 8
+.SH NAME
+amrmtape \- remove a tape from the Amanda database
+.SH SYNOPSIS
+.B amrmtape
+[
+.B -n
+] [
+.B -v
+] [
+.B -q
+] [
+.B -d
+]
+.I config
+.I label
+.SH DESCRIPTION
+.B 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.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH OPTIONS
+.TP
+.B -n
+Generate new
+.I tapelist
+and database files with
+.I label
+removed, but leave them in
+.I /tmp
+and do not update the original copies.
+.TP
+.B -v
+List backups of hosts and disks that are being discarded.  Enabled by default.
+.TP
+.B -q
+Opposite of
+.BR -v .
+.TP
+.B -d
+Run in debugging mode so all executed commands are shown.
+.SH EXAMPLE
+Remove tape labeled
+.I DAILY034
+from the
+.I DailySet1
+configuration.
+.LP
+.RS
+.EX
+# amrmtape DailySet1 DAILY034
+.EE
+.RE
+.SH AUTHOR
+Adrian T. Filipi-Martin <atf3r@cs.virginia.edu>
+.SH "SEE ALSO"
+amadmin(8),
+amanda(8)
diff --git a/man/amstatus.8.in b/man/amstatus.8.in
new file mode 100644 (file)
index 0000000..977f503
--- /dev/null
@@ -0,0 +1,104 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.de P1
+\fB\\$1\fP \fI\\$2\fP \\$3 \fI\\$4\fP \\$5
+..
+.de P2
+\fB\\$1\fP \fI\\$2\fP \fI\\$3\fP
+..
+.de P3
+\fB\\$1\fP \\$2 \fI\\$3\fP \\$4 \fI\\$5\fP \\$6 \\$7
+..
+.TH AMSTATUS 8
+.SH NAME
+amstatus \- display the state of an Amanda run
+.SH SYNOPSIS
+.B amstatus
+[--config]
+.I config
+[--file 
+.I amdumpfile
+]
+[--summary]
+[--dumping]
+[--waitdumping]
+[--waittaper]
+[--dumpingtape]
+[--writingtape]
+[--finished]
+[--failed]
+[--estimate]
+[--gestimate]
+[--stats]
+.SH DESCRIPTION
+.B Amstatus
+gives the current state of the Amanda run specified by the 
+.I 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.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH OPTIONS
+All options may be abbreviated to the shortest non-ambiguous sub-string.
+If no options are given, everything is displayed.
+.TP
+.B "[--config]" config
+Specify the Amanda configuration you want to display the state for.
+.TP
+.B --file amdumpfile
+Specify an alternate file instead of the
+.I amdump
+or
+.I amflush
+file.
+.TP
+.B --summary
+Display a summary of the state of the run.
+.TP
+.B --dumping
+Display all partitions that are dumping.
+.TP
+.B --waitdumping|wdumping
+Display all partitions that are waiting to be dumped.
+.TP
+.B --waittaper|wtaper
+Display all partitions dumped that are waiting to be written to tape.
+.TP
+.B --dumpingtape|dtape
+Display all partitions that are dumping directly to tape.
+.TP
+.B --writingtape|wtape
+Display all partitions that are writing to tape.
+.TP
+.B --finished
+Display all partitions that are dumped and written to tape.
+.TP
+.B --failed|error
+Display all partitions that failed.
+.TP
+.B --estimate
+Display all partitions whose estimate is finished.
+Works only during the estimate phase.
+.TP
+.B --gestimate|gettingestimate
+Display all partitions whose estimate is not finished.
+Works only during the estimate phase.
+.TP
+.B --stats|statistics
+Display statistics about active-time of taper and dumpers.
+.SH "SEE ALSO"
+amanda(8),
+amcheck(8),
+amdump(8),
+amrestore(8),
+amadmin(8)
diff --git a/man/amtape.8 b/man/amtape.8
new file mode 100644 (file)
index 0000000..c31c207
--- /dev/null
@@ -0,0 +1,144 @@
+.\"
+.de CO
+\fB\\$1\fP \fI\\$2\fP
+..
+.TH AMTAPE 8
+.SH NAME
+amtape \- user interface to Amanda tape changer controls
+.SH SYNOPSIS
+.B amtape
+.I config
+.I command
+[
+.I command options
+]
+.SH DESCRIPTION
+.B Amtape
+performs tape changer control operations.
+It uses the underlying tape changer script defined by the
+.B tpchanger
+option for a particular Amanda
+configuration as specified by the
+.I config
+argument.
+.LP
+Tape changers maintain a notion of the
+.I current
+and
+.I 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.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH COMMANDS
+.TP
+.B reset
+Reset the tape changer to a known state.
+The
+.I current
+slot is set to the
+.I 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.
+.TP
+.B eject
+If a tape is loaded in the drive, it is ejected and returned to the
+slot from which it was loaded.
+.TP
+.B clean
+If a cleaning tape is defined for the changer,
+it is used to clean the drive.
+.TP
+.B show
+Show the contents of all slots.
+This can be slow.
+.TP
+.CO label label
+Search for and load the Amanda tape with label
+.IR label .
+.TP
+.B taper
+Perform the
+.B taper
+scan algorithm.
+Load the next tape in the configuration's tape sequence,
+or a fresh tape with a suitable label.
+.TP
+.B device
+Display the name of the current tape device on
+.IR stdout .
+.TP
+.B current
+Display the current slot.
+.TP
+.B update
+Update the changer label database, if it has one,
+to match the tapes now available.
+.TP
+.CO slot slot
+Eject any tape in the drive and put it away,
+then load the tape from slot
+.I slot
+and reset
+.IR current .
+.TP
+.B slot current
+Eject any tape in the drive and put it away,
+then load the tape from the current slot.
+.TP
+.B slot prev
+Eject any tape in the drive and put it away,
+then load the tape from the previous slot and reset
+.IR current .
+.TP
+.B slot next
+Eject any tape in the drive and put it away,
+then load the tape from the next slot and reset
+.IR current .
+.TP
+.B slot first
+Eject any tape in the drive and put it away,
+then load the tape from the first slot and reset
+.IR current .
+.TP
+.B slot last
+Eject any tape in the drive and put it away,
+then load the tape from the last slot and reset
+.IR current .
+.TP
+.B slot advance
+Eject any tape in the drive and put it away.
+Advance
+.I current
+to the next tape, but do not load it.
+.IP
+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
+.BR 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
+.B slot next
+followed by
+.B eject
+does an unnecessary mount.
+.LP
+Note: most changers optimize the
+.B slot
+commands to not eject the loaded tape if it is the one being requested.
+.SH AUTHOR
+James da Silva <jds@cs.umd.edu>
+.br
+University of Maryland, College Park
+.SH "SEE ALSO"
+amanda(8)
diff --git a/man/amtapetype.8.in b/man/amtapetype.8.in
new file mode 100644 (file)
index 0000000..a183d23
--- /dev/null
@@ -0,0 +1,104 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMTAPETYPE 8
+.SH NAME
+amtapetype \- generate a tapetype definition.
+.SH SYNOPSIS
+.B amtapetype
+[-h]
+[-c]
+[-b blocksize]
+[-e estsize]
+[-f tapedev]
+[-t typename]
+.SH DESCRIPTION
+.B Amtapetype
+generate a tapetype entry for amanda.
+.SH OPTIONS
+.PP
+.TP 10
+.B \-h
+Display an help message.
+.TP
+.B \-c
+Run only the hardware compression detection heuristic test and stop.
+This takes a few minutes only.
+.TP
+.BI \-b "\| blocksize\^"
+record block size (default: 32k)
+.TP
+.BI \-e "\| estsize\^"
+estimated tape size (default: 1g == 1024m)
+.TP
+.BI \-f "\| tapedev\^"
+tape device name (default: $TAPE)
+The device to perform the test.
+.TP
+.BI \-t "\| typename\^"
+tapetype name (default: unknown-tapetype)
+.PD
+.SH EXAMPLE
+Generate a tapetype definition for your tape device:
+.LP
+.RS
+.nf
+% amtapetype -f @DEFAULT_TAPE_DEVICE@
+.SH NOTES
+Hardware compression is detected by measuring
+the writing speed difference of the tape drive
+when writing an amount of compressable and uncompresseable data.
+It does not rely on the status bits of the tape drive or the OS parameters.
+If your tape drive has very large buffers or is very fast, the program
+could fail to detect hardware compression status reliably.
+
+During the first pass, it writes files that are estimated to be 1%
+of the expected tape capacity.  It gets the expected capacity from
+the -e command line flag, or defaults to 1 GByte.  In a perfect world
+(which means there is zero chance of this happening with tapes :-),
+there would be 100 files and 100 file marks.
+
+During the second pass, the file size is cut in half.  In that same
+fairyland world, this means 200 files and 200 file marks.
+
+In both passes the total amount of data written is summed as well as the
+number of file marks written.  At the end of the second pass, quoting
+from the code:
+
+   * Compute the size of a filemark as the difference in data written
+   * between pass 1 and pass 2 divided by the difference in number of
+   * file marks written between pass 1 and pass 2.  ...
+
+So if we wrote 1.0 GBytes on the first pass and 100 file marks, and
+0.9 GBytes on the second pass with 200 file marks, those additional 100
+file marks in the second pass took 0.1 GBytes and therefor a file mark
+is 0.001 GBytes (1 MByte).
+
+Note that if the estimated capacity is wrong, the only thing that happens
+is a lot more (or less, but unlikely) files, and thus, file marks,
+get written.  But the math still works out the same.  The -e flag is
+there to keep the number of file marks down because they can be slow
+(since they force the drive to flush all its buffers to physical media).
+
+All sorts of things might happen to cause the amount of data
+written to vary enough to generate a big file mark size guess.  A little
+more "shoe shining" because of the additional file marks (and flushes),
+dirt left on the heads from the first pass of a brand new tape, the
+temperature/humidity changed during the multi-hour run, a different amount
+of data was written after the last file mark before EOT was reported, etc.
+
+Note that the file mark size might really be zero for whatever device this
+is, and it was just the measured capacity variation that caused amtapetype
+to think those extra file marks in pass 2 actually took up space.
+
+It also explains why amtapetype used to sometimes report a negative file
+mark size if the math happened to end up that way.  When that happens
+now we just report it as zero.
+.SH "SEE ALSO"
+amanda(8)
diff --git a/man/amtoc.8.in b/man/amtoc.8.in
new file mode 100644 (file)
index 0000000..6dde1bf
--- /dev/null
@@ -0,0 +1,128 @@
+.TH AMTOC 8 
+.de CP
+.ie '\\$3'' \\fB\\$1\\fP \\fI\\$2\\fP
+.el .ie '\\$2'' \\fB\\$1\\fP [ \\fI\\$3\\fP ]
+.el \\fB\\$1\\fP \\fI\\$2\\fP [ \\fI\\$3\\fP ]
+..
+.SH NAME 
+amtoc \- generate TOC (Table Of Contents) for an Amanda run
+.SH SYNOPSIS
+.B
+.I amtoc
+[
+.B \-a
+] [
+.B \-i
+] [
+.B \-t
+] [
+.B \-f
+.I file
+] [
+.B \-s
+.I subs
+] [
+.B \-w
+] [
+.B \--
+]
+.I logfile
+.SH DESCRIPTION
+.I Amtoc 
+generates a table of contents for an Amanda run.
+It's a perl script (if you don't have perl, install it first!).
+.SH OPTIONS
+.TP
+.B \-a
+The output file name will be
+.IR label-of-the-tape .toc
+in the same directory as
+.IR logfile .
+.TP
+.B \-i
+Display help about
+.BR amtoc .
+.TP
+.B \-t
+Generate the output in tabular form.
+.TP
+.B \-f file
+Write the output to a file ('-' for stdout).
+.TP 
+.B \-s subs
+Evaluate the output file name from
+.IR subs ,
+with $_ set to
+.IR label-of-the-tape .
+The
+.B -a
+option is equivalent to
+.B -s
+.IR 's/$_/.toc/' .
+.TP
+.B \-w
+Separate tapes with form-feeds and display blank lines before totals.
+.TP
+.B \-\-
+Marks the last option so the next parameter is the
+.IR logfile .
+.TP
+.B logfile
+(use '-' for stdin)
+.SH OUTPUT FORMAT
+The standard output has five fields separated by two spaces:
+.LP
+.RS
+.nf
+#  Server:/partition  date  level  size[Kb]
+0  daily-05:  19991005  -  -
+1  cuisun15:/cuisun15/home  19991005  1  96
+2  cuinfs:/export/dentiste  19991005  1  96
+  ...
+103  cuisg11:/  19991005  0  4139136
+103  total:  -  -  16716288
+.RE
+.LP
+In tabular format (-t), this would look like:
+.LP
+.RS
+.nf
+  #  Server:/partition           date      lev  size[Kb]
+  0  daily-05:                   19991005    -         -
+  1  cuisun15:/cuisun15/home     19991005    1        96
+  2  cuinfs:/export/dentiste     19991005    1        96
+  ...
+103  cuisg11:/                   19991005    0   4139136
+103  total:                      -           -  16716288
+.RE
+.SH USAGE
+The easiest way to use it is to run
+.I amtoc
+right after
+.I amdump
+in the
+.I
+cron job:
+.LP
+.RS  
+.nf
+amdump @DEFAULT_CONFIG@ ; logdir=`amgetconf @DEFAULT_CONFIG@ logdir` ; log=`ls -1t $logdir/log.*.[0-9] | head -1` ; amtoc -a $log
+.fi
+.RE  
+.LP
+which will generate @CONFIG_DIR@/@DEFAULT_CONFIG@/\fItape_label\fR.toc.
+You may also want to call
+.I amtoc
+after an
+.IR amflush .
+.SH SEE ALSO
+amanda(8),
+amdump(8),
+amflush(8),
+amgetconf(8),
+cron,
+perl
+.SH AUTHOR
+Nicolas MAYENCOURT <Nicolas.Mayencourt@cui.unige.ch>
+.br
+University of Geneva/Switzerland
diff --git a/man/amverify.8.in b/man/amverify.8.in
new file mode 100644 (file)
index 0000000..371e9e4
--- /dev/null
@@ -0,0 +1,71 @@
+.\"
+.de EX
+.if t .ft C
+.nf
+..
+.de EE
+.fi
+.if t .ft
+..
+.TH AMVERIFY 8
+.SH NAME
+amverify \- check an Amanda tape for errors
+.SH SYNOPSIS
+.B amverify
+.I config
+[
+.I slot
+[
+.I runtapes
+]
+]
+.SH DESCRIPTION
+.B Amverify
+reads an Amanda format tape and makes sure each backup image
+can be processed by
+.B amrestore
+and, if possible, the appropriate restore program (e.g.\&
+.BR tar ).
+.LP
+.B Amverify
+runs
+.B amrestore
+on each file of the tape and pipes the output
+to a restore program (if available) with an option to create a catalogue
+of the backup.
+The catalogue itself is discarded.
+Only the success or failure of the operation itself is reported.
+.LP
+If the backup image cannot be processed by the restore program,
+e.g. if it was written on a different operating system,
+the image is sent through
+.B dd
+to /dev/null.
+This still determines if the tape is readable,
+but does not do any internal consistency check on the image.
+.LP
+If
+.I config
+is set up to use a tape changer,
+the
+.I slot
+argument may be used to choose the first tape to process.
+Otherwise,
+the
+.B current
+slot is used.
+.LP
+The
+.B runtapes
+configuration parameter determines how many tapes are processed unless
+it is specified on the command line.
+.LP
+See the
+.IR amanda (8)
+man page for more details about Amanda.
+.SH AUTHOR
+Axel Zinser <fifi@icem.de>
+.SH "SEE ALSO"
+amrestore(8),
+amanda(8),
+amverifyrun(8)
diff --git a/man/amverifyrun.8.in b/man/amverifyrun.8.in
new file mode 100644 (file)
index 0000000..684305c
--- /dev/null
@@ -0,0 +1,17 @@
+.TH AMVERIFYRUN 8
+.SH NAME
+amverifyrun \- check the tapes written by the last amanda run
+.SH SYNOPSIS
+.B amverifyrun
+.I config
+.SH DESCRIPTION
+.B 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
+.B amverify
+with these argument.
+.LP
+.SH "SEE ALSO"
+amanda(8),
+amverify(8)
diff --git a/patches/regex-3.6alpha.patch b/patches/regex-3.6alpha.patch
new file mode 100644 (file)
index 0000000..2f55c41
--- /dev/null
@@ -0,0 +1,90 @@
+Index: regex2.h
+===================================================================
+RCS file: /homes/amcore/cvsroot/amanda-2/regex-src/regex2.h,v
+retrieving revision 1.2
+retrieving revision 1.4
+diff -u -r1.2 -r1.4
+--- regex2.h   1997/09/30 06:28:57     1.2
++++ regex2.h   1997/11/07 20:43:30     1.4
+@@ -44,28 +44,40 @@
+ #define       OP(n)   ((n)&OPRMASK)
+ #define       OPND(n) ((n)&OPDMASK)
+ #define       SOP(op, opnd)   ((op)|(opnd))
++
++#ifndef UNSIGNEDLONG1
++#ifndef NO_UL_CNSTS
++#define UNSIGNEDLONG1 1ul
++#else
++#define UNSIGNEDLONG1 ((unsigned long)1)
++#endif
++#endif
++
++#define MAKE_UNSIGNED_LONG(num) (UNSIGNEDLONG1*num)
++#define SHIFTED_UL(num) (MAKE_UNSIGNED_LONG(num) << OPSHIFT)
++
+ /* operators                     meaning      operand                 */
+ /*                                            (back, fwd are offsets) */
+-#define       OEND    (1ul<<OPSHIFT)  /* endmarker    -                       */
+-#define       OCHAR   (2ul<<OPSHIFT)  /* character    unsigned char           */
+-#define       OBOL    (3ul<<OPSHIFT)  /* left anchor  -                       */
+-#define       OEOL    (4ul<<OPSHIFT)  /* right anchor -                       */
+-#define       OANY    (5ul<<OPSHIFT)  /* .            -                       */
+-#define       OANYOF  (6ul<<OPSHIFT)  /* [...]        set number              */
+-#define       OBACK_  (7ul<<OPSHIFT)  /* begin \d     paren number            */
+-#define       O_BACK  (8ul<<OPSHIFT)  /* end \d       paren number            */
+-#define       OPLUS_  (9ul<<OPSHIFT)  /* + prefix     fwd to suffix           */
+-#define       O_PLUS  (10ul<<OPSHIFT) /* + suffix     back to prefix          */
+-#define       OQUEST_ (11ul<<OPSHIFT) /* ? prefix     fwd to suffix           */
+-#define       O_QUEST (12ul<<OPSHIFT) /* ? suffix     back to prefix          */
+-#define       OLPAREN (13ul<<OPSHIFT) /* (            fwd to )                */
+-#define       ORPAREN (14ul<<OPSHIFT) /* )            back to (               */
+-#define       OCH_    (15ul<<OPSHIFT) /* begin choice fwd to OOR2             */
+-#define       OOR1    (16ul<<OPSHIFT) /* | pt. 1      back to OOR1 or OCH_    */
+-#define       OOR2    (17ul<<OPSHIFT) /* | pt. 2      fwd to OOR2 or O_CH     */
+-#define       O_CH    (18ul<<OPSHIFT) /* end choice   back to OOR1            */
+-#define       OBOW    (19ul<<OPSHIFT) /* begin word   -                       */
+-#define       OEOW    (20ul<<OPSHIFT) /* end word     -                       */
++#define       OEND    (SHIFTED_UL(1)) /* endmarker    -                       */
++#define       OCHAR   (SHIFTED_UL(2)) /* character    unsigned char           */
++#define       OBOL    (SHIFTED_UL(3)) /* left anchor  -                       */
++#define       OEOL    (SHIFTED_UL(4)) /* right anchor -                       */
++#define       OANY    (SHIFTED_UL(5)) /* .            -                       */
++#define       OANYOF  (SHIFTED_UL(6)) /* [...]        set number              */
++#define       OBACK_  (SHIFTED_UL(7)) /* begin \d     paren number            */
++#define       O_BACK  (SHIFTED_UL(8)) /* end \d       paren number            */
++#define       OPLUS_  (SHIFTED_UL(9)) /* + prefix     fwd to suffix           */
++#define       O_PLUS  (SHIFTED_UL(10))        /* + suffix     back to prefix          */
++#define       OQUEST_ (SHIFTED_UL(11))        /* ? prefix     fwd to suffix           */
++#define       O_QUEST (SHIFTED_UL(12))        /* ? suffix     back to prefix          */
++#define       OLPAREN (SHIFTED_UL(13))        /* (            fwd to )                */
++#define       ORPAREN (SHIFTED_UL(14))        /* )            back to (               */
++#define       OCH_    (SHIFTED_UL(15))        /* begin choice fwd to OOR2             */
++#define       OOR1    (SHIFTED_UL(16))        /* | pt. 1      back to OOR1 or OCH_    */
++#define       OOR2    (SHIFTED_UL(17))        /* | pt. 2      fwd to OOR2 or O_CH     */
++#define       O_CH    (SHIFTED_UL(18))        /* end choice   back to OOR1            */
++#define       OBOW    (SHIFTED_UL(19))        /* begin word   -                       */
++#define       OEOW    (SHIFTED_UL(20))        /* end word     -                       */
+ /*
+  * Structure for [] character-set representation.  Character sets are
+Index: regexec.c
+===================================================================
+RCS file: /homes/amcore/cvsroot/amanda-2/regex-src/regexec.c,v
+retrieving revision 1.2
+retrieving revision 1.4
+diff -u -r1.2 -r1.4
+--- regexec.c  1997/09/30 06:28:59     1.2
++++ regexec.c  1997/11/07 20:43:32     1.4
+@@ -22,9 +22,9 @@
+ #define       states  long
+ #define       states1 states          /* for later use in regexec() decision */
+ #define       CLEAR(v)        ((v) = 0)
+-#define       SET0(v, n)      ((v) &= ~(1ul << (n)))
+-#define       SET1(v, n)      ((v) |= 1ul << (n))
+-#define       ISSET(v, n)     ((v) & (1ul << (n)))
++#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       EQ(a, b)        ((a) == (b))
+ #define       STATEVARS       int dummy       /* dummy version */
diff --git a/patches/samba-largefs.patch b/patches/samba-largefs.patch
new file mode 100644 (file)
index 0000000..7bb4d59
--- /dev/null
@@ -0,0 +1,56 @@
+This patch fixes Samba 2.0.0 up to 2.0.3, so that it does not overflow
+on filesystems larger than 2GB.  The problem is fixed in newer
+releases of Samba.
+
+Index: client/client.c
+--- client/client.c    1999/01/27 19:37:27     1.125
++++ client/client.c    1999/03/30 10:25:18     1.128
+@@ -101,7 +101,7 @@
+ int put_total_time_ms = 0;
+ /* totals globals */
+-int dir_total = 0;
++static double dir_total;
+ #define USENMB
+@@ -430,7 +430,7 @@
+       do_dskattr();
+-      DEBUG(3, ("Total bytes listed: %d\n", dir_total));
++      DEBUG(3, ("Total bytes listed: %.0f\n", dir_total));
+ }
+@@ -463,7 +463,7 @@
+       do_dskattr();
+-      DEBUG(0, ("Total number of bytes: %d\n", dir_total));
++      DEBUG(0, ("Total number of bytes: %.0f\n", dir_total));
+ }
+Index: client/clitar.c
+--- client/clitar.c    1999/02/03 16:30:54     1.67
++++ client/clitar.c    1999/03/30 10:41:07     1.70
+@@ -85,7 +85,8 @@
+ #endif
+ static char *tarbuf, *buffer_p;
+-static int tp, ntarf, tbufsiz, ttarf;
++static int tp, ntarf, tbufsiz;
++static double ttarf;
+ /* Incremental mode */
+ BOOL tar_inc=False;
+ /* Reset archive bit */
+@@ -1486,7 +1487,7 @@
+     free(tarbuf);
+     
+     DEBUG(0, ("tar: dumped %d tar files\n", ntarf));
+-    DEBUG(0, ("Total bytes written: %d\n", ttarf));
++    DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
+     break;
+   }
diff --git a/patches/tar-1.12.patch b/patches/tar-1.12.patch
new file mode 100644 (file)
index 0000000..0a554da
--- /dev/null
@@ -0,0 +1,173 @@
+The first hunk in this file was submitted by Craig Wiegert
+<wiegert@quintessence.uchicago.edu>.  It fixed a problem that causes
+GNUTAR to issue error messages like the following for sparse files:
+
+> /bin/tar: Read error at byte 0, reading 512 bytes, in file ./var/log/lastlog: Bad file number
+
+The others fix an estimate problem in GNUTAR on SunOS 4.1.3, HP/UX and
+other systems whose C libraries do not support "%lld" in printf format
+strings for printing long long integers.
+
+--- tar-1.12/src/create.c      Mon Dec 15 17:26:47 1997
++++ tar-1.12/src/create.c      Mon Dec 15 17:50:48 1997
+@@ -1048,7 +1048,7 @@
+       }
+       if (save_typeflag == GNUTYPE_SPARSE)
+       {
+-        if (finish_sparse_file (f, &sizeleft, current_stat.st_size, p))
++        if (f < 0 || finish_sparse_file (f, &sizeleft, current_stat.st_size, p))
+           goto padit;
+       }
+       else
+--- tar-1.12/lib/Makefile.am   Wed Apr 16 16:30:04 1997
++++ tar-1.12/lib/Makefile.am   Mon Nov 17 06:45:43 1997
+@@ -37,6 +37,9 @@
+ libtar_a_LIBADD = @ALLOCA@ @LIBOBJS@
+ libtar_a_DEPENDENCIES = $(libtar_a_LIBADD)
++$(srcdir)/getdate.h:
++      touch $@
++
+ # Say $(srcdir), so GNU make does not report an ambiguity with the .y.c rule.
+ $(srcdir)/getdate.c: getdate.y
+       @echo Expect 13 shift/reduce conflicts...
+--- tar-1.12/src/arith.h       Wed Apr 16 18:02:57 1997
++++ tar-1.12/src/arith.h       Mon Nov 17 05:47:33 1997
+@@ -37,10 +37,10 @@
+ #if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= BITS_PER_TARLONG
+ # define SUPERDIGIT 0
+-# define TARLONG_FORMAT "%uld"
++# define TARLONG_FORMAT "%lu"
+ typedef unsigned long tarlong;
+ #else
+-# if BITS_PER_BYTE * SIZEOF_LONG_LONG >= BITS_PER_TARLONG + 1
++# if PRINTF_LONG_LONG_WORKS && BITS_PER_BYTE * SIZEOF_LONG_LONG >= BITS_PER_TARLONG + 1
+ #  define SUPERDIGIT 0
+ #  define TARLONG_FORMAT "%lld"
+ typedef long long tarlong;
+@@ -48,12 +48,12 @@
+ #  if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= 64
+ #   define SUPERDIGIT 1000000000L
+ #   define BITS_PER_SUPERDIGIT 29
+-#   define TARLONG_FORMAT "%09uld"
++#   define TARLONG_FORMAT "%09lu"
+ #  else
+ #   if BITS_PER_BYTE * SIZEOF_UNSIGNED_LONG >= 32
+ #    define SUPERDIGIT 10000L
+ #    define BITS_PER_SUPERDIGIT 14
+-#    define TARLONG_FORMAT "%04uld"
++#    define TARLONG_FORMAT "%04lu"
+ #   endif
+ #  endif
+ # endif
+--- tar-1.12/src/arith.c       Wed Apr 23 23:25:57 1997
++++ tar-1.12/src/arith.c       Mon Nov 17 08:11:11 1997
+@@ -96,7 +96,7 @@
+ void
+ add_to_tarlong_helper (unsigned long *accumulator, int value)
+ {
+-  int counter;
++  int counter, newvalue;
+   if (value < 0)
+     for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
+@@ -106,8 +106,15 @@
+           accumulator[counter] += value;
+           return;
+         }
+-      accumulator[counter] += value + SUPERDIGIT;
+-      value = -1;
++      newvalue = - ((-value-1) / SUPERDIGIT) -1;
++      value = - ((-value) % SUPERDIGIT);
++      accumulator[counter] += SUPERDIGIT + value;
++      if (accumulator[counter] >= SUPERDIGIT)
++        {
++          accumulator[counter] -= SUPERDIGIT;
++          ++newvalue;
++        }
++      value = newvalue;
+       }
+   else
+     for (counter = 0; counter < LONGS_PER_TARLONG; counter++)
+@@ -117,8 +124,15 @@
+           accumulator[counter] += value;
+           return;
+         }
+-      accumulator[counter] += value - SUPERDIGIT;
+-      value = 1;
++      newvalue = value / SUPERDIGIT;
++      value = value % SUPERDIGIT;
++      accumulator[counter] += value;
++      if (accumulator[counter] >= SUPERDIGIT)
++        {
++          accumulator[counter] -= SUPERDIGIT;
++          ++newvalue;
++        }
++      value = newvalue;
+       }
+   FATAL_ERROR ((0, 0, _("Arithmetic overflow")));
+ }
+@@ -155,7 +169,7 @@
+   while (counter > 0 && accumulator[counter] == 0)
+     counter--;
+-  fprintf (file, "%uld", accumulator[counter]);
++  fprintf (file, "%lu", accumulator[counter]);
+   while (counter > 0)
+     fprintf (file, TARLONG_FORMAT, accumulator[--counter]);
+ }
+--- tar-1.12/configure.in      Fri Apr 25 17:02:46 1997
++++ tar-1.12/configure.in      Mon Nov 17 06:17:49 1997
+@@ -26,6 +26,35 @@
+ AC_CHECK_SIZEOF(unsigned long, 4)
+ AC_CHECK_SIZEOF(long long, 0)
++# SunOS 4.1.3's printf treats %lld as %ld
++AC_CACHE_CHECK([whether printf understands %lld],
++      tar_cv_printf_long_long_works,
++      AC_TRY_RUN([[
++#include <stdio.h>
++main() {
++  long long foo = -1;
++  char buf[1024];
++  while(foo) {
++    long long bar = 0;
++    sprintf(buf, "%lld", foo);
++    sscanf(buf, "%lld", &bar);
++    if (foo != bar)
++      return 1;
++    foo <<= 1;
++  }
++  return 0;
++}
++      ]], 
++      tar_cv_printf_long_long_works=yes,
++      tar_cv_printf_long_long_works=no,
++      if test x"$tar_cv_printf_long_long_works" = x; then
++              tar_cv_printf_long_long_works=cross
++      fi)
++)
++if test x"$tar_cv_printf_long_long_works" = x"yes"; then
++      AC_DEFINE(PRINTF_LONG_LONG_WORKS)
++fi
++
+ AC_CHECK_HEADERS(fcntl.h limits.h linux/fd.h memory.h net/errno.h poll.h \
+ sgtty.h string.h stropts.h \
+ sys/buf.h sys/device.h sys/gentape.h sys/inet.h sys/io/trioctl.h sys/ioccom.h \
+--- tar-1.12/acconfig.h        Thu Apr 10 11:37:02 1997
++++ tar-1.12/acconfig.h        Mon Nov 17 05:53:38 1997
+@@ -86,3 +86,6 @@
+ /* Define to 1 if GNU regex should be used instead of GNU rx.  */
+ #undef WITH_REGEX
++
++/* Define to 1 if printf() supports "%lld" */
++#undef PRINTF_LONG_LONG_WORKS
+--- tar-1.12/configure
++++ tar-1.12/configure
+@@ -1,2 +1,4 @@
+ #! /bin/sh
++echo You must run autoheader and autoconf after installing this patch
++exit 1
diff --git a/recover-src/Makefile.am b/recover-src/Makefile.am
new file mode 100644 (file)
index 0000000..042feba
--- /dev/null
@@ -0,0 +1,50 @@
+# Makefile for Amanda file recovery programs.
+
+INCLUDES =             -I$(top_srcdir)/common-src -I$(top_srcdir)/client-src \
+                       -I$(top_srcdir)/tape-src
+
+LIB_EXTENSION = la
+
+sbin_PROGRAMS =                amrecover
+
+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) \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
+       $(READLINE_LIBS)
+
+amrecover_SOURCES =    amrecover.c                                     \
+                       display_commands.c              extract_list.c  \
+                       help.c                          set_commands.c  \
+                       uparse.y                        uscan.l
+
+noinst_HEADERS =       amrecover.h uparse.h
+
+AM_YFLAGS =            -d
+
+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
+
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
diff --git a/recover-src/Makefile.in b/recover-src/Makefile.in
new file mode 100644 (file)
index 0000000..c8aec56
--- /dev/null
@@ -0,0 +1,643 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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.
+
+
+SOURCES = $(amrecover_SOURCES)
+
+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 = :
+host_triplet = @host@
+sbin_PROGRAMS = amrecover$(EXEEXT)
+subdir = recover-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_amrecover_OBJECTS = amrecover.$(OBJEXT) display_commands.$(OBJEXT) \
+       extract_list.$(OBJEXT) help.$(OBJEXT) set_commands.$(OBJEXT) \
+       uparse.$(OBJEXT) uscan.$(OBJEXT)
+amrecover_OBJECTS = $(am_amrecover_OBJECTS)
+amrecover_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+amrecover_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       ../client-src/libamclient.$(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
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/amrecover.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/display_commands.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/extract_list.Po ./$(DEPDIR)/help.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/set_commands.Po ./$(DEPDIR)/uparse.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/uscan.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --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 = $(amrecover_SOURCES)
+DIST_SOURCES = $(amrecover_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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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_srcdir)/common-src -I$(top_srcdir)/client-src \
+                       -I$(top_srcdir)/tape-src
+
+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) \
+       ../common-src/libamanda.$(LIB_EXTENSION) \
+       $(READLINE_LIBS)
+
+amrecover_SOURCES = amrecover.c                                        \
+                       display_commands.c              extract_list.c  \
+                       help.c                          set_commands.c  \
+                       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  recover-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  recover-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
+amrecover$(EXEEXT): $(amrecover_OBJECTS) $(amrecover_DEPENDENCIES) 
+       @rm -f amrecover$(EXEEXT)
+       $(LINK) $(amrecover_LDFLAGS) $(amrecover_OBJECTS) $(amrecover_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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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 "/^#/ s/Y_TAB_H/$$to/g" 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 -z "$$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:
+       -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.h
+       -rm -f uscan.c
+       -rm -f uparse.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-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
+
+
+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
+
+# so that uscan.c is never generated before uparse.h
+# otherwise we might have makedepend problems
+$(srcdir)/uscan.c: $(srcdir)/uparse.h
+# 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/recover-src/amrecover.c b/recover-src/amrecover.c
new file mode 100644 (file)
index 0000000..1a54b1f
--- /dev/null
@@ -0,0 +1,686 @@
+/*
+ * 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.29.4.7.4.6.2.7 2003/01/04 04:33:32 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"
+
+#if defined(KRB4_SECURITY)
+#include "krb4-security.h"
+#endif
+#include "util.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));
+
+#define USAGE "Usage: amrecover [[-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 *their_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
+
+/* 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 ()
+{
+    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;
+           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;
+       }
+       /*
+        * 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");
+    }
+}
+
+
+/* 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 (show)
+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 ()
+{
+    if (get_line() == -1)
+       return -1;
+    return server_line[3] == '-';
+}
+
+
+/* returns pointer to returned line */
+char *reply_line ()
+{
+    return server_line;
+}
+
+
+
+/* returns 0 if server returned an error code (ie code starting with 5)
+   and non-zero otherwise */
+int server_happy ()
+{
+    return server_line[0] != '5';
+}
+
+
+int send_command(cmd)
+char *cmd;
+{
+    size_t l, n;
+    ssize_t s;
+    char *end;
+
+    /*
+     * 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 routines here.
+     */
+    for (l = 0, n = strlen(cmd); l < n; l += s)
+       if ((s = write(server_socket, cmd + l, n - l)) < 0) {
+           perror("amrecover: Error writing to server");
+           return -1;
+       }
+    end = "\r\n";
+    for (l = 0, n = strlen(end); l < n; l += s)
+       if ((s = write(server_socket, end + l, n - l)) < 0) {
+           perror("amrecover: Error writing to server");
+           return -1;
+       }
+    return 0;
+}
+
+
+/* send a command to the server, get reply and print to screen */
+int converse(cmd)
+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(cmd)
+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(signum)
+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.
+     */
+    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(s)
+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 (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 ()
+{
+    quit_prog = 1;
+    (void)converse("QUIT");
+}
+
+char *localhost = NULL;
+
+int main(argc, argv)
+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;
+    int fd;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("amrecover");
+    dbopen();
+
+#ifndef IGNORE_UID_CHECK
+    if (geteuid() != 0) {
+       erroutput_type |= ERR_SYSLOG;
+       error("amrecover must be run by root");
+    }
+#endif
+
+    localhost = alloc(MAX_HOSTNAME_LENGTH+1);
+    if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) {
+       error("cannot determine local host name\n");
+    }
+    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] != '-')
+    {
+       /*
+        * 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 ((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';
+
+    /* 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));
+    }
+
+    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);
+    }
+    amfree(service_name);
+    server_socket = stream_client_privileged(server_name,
+                                            ntohs(sp->s_port),
+                                            -1,
+                                            -1,
+                                            &my_port);
+    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);
+    }
+
+#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)
+       exit(1);
+    if (!server_happy())
+    {
+       dbclose();
+       aclose(server_socket);
+       exit(1);
+    }
+
+    /* do the security thing */
+#if defined(KRB4_SECURITY)
+#if 0 /* not yet implemented */
+    if(krb4_auth)
+    {
+       line = get_krb_security();
+    } else
+#endif /* 0 */
+#endif
+    {
+       line = get_bsd_security();
+    }
+    if (converse(line) == -1)
+       exit(1);
+    if (!server_happy())
+       exit(1);
+    memset(line, '\0', strlen(line));
+    amfree(line);
+
+    /* try to get the features form 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);
+           their_features = am_string_to_feature(their_feature_string);
+       }
+       else {
+           their_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));
+    printf("Setting restore date to today (%s)\n", dump_date);
+    line = stralloc2("DATE ", dump_date);
+    if (converse(line) == -1)
+       exit(1);
+    amfree(line);
+
+    line = stralloc2("SCNF ", config);
+    if (converse(line) == -1)
+       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("Can't determine disk and mount point from $CWD '%s'\n", cwd);
+                   /* 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;
+}
diff --git a/recover-src/amrecover.h b/recover-src/amrecover.h
new file mode 100644 (file)
index 0000000..eb937f8
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * 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.8.4.2.4.1.2.3 2002/10/27 21:13:25 martinea Exp $
+ *
+ * data structures and declarations for amrecover
+ */
+
+#include "amanda.h"
+#include "amfeatures.h"
+
+typedef struct DIR_ITEM
+{
+    char date[11];
+    int  level;
+    char tape[256];
+    char path[1024];
+    int  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 *their_features;
+extern pid_t extract_restore_child_pid;
+
+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 void quit P((void));
+
+extern void help_list P((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 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 extract_files P((void));
+
+#ifdef SAMBA_CLIENT
+#define SAMBA_SMBCLIENT 0
+#define SAMBA_TAR       1
+#endif
diff --git a/recover-src/display_commands.c b/recover-src/display_commands.c
new file mode 100644 (file)
index 0000000..1797db5
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * 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.12.4.1.6.3 2002/10/27 21:13:25 martinea Exp $
+ *
+ * implements the directory-display related commands in amrecover
+ */
+
+#include "amanda.h"
+#include "amrecover.h"
+
+static DIR_ITEM *dir_list = NULL;
+
+DIR_ITEM *get_dir_list P((void))
+{
+    return dir_list;
+}
+
+DIR_ITEM *get_next_dir_item(this)
+DIR_ITEM *this;
+{
+    return this->next;
+}
+
+
+void clear_dir_list P((void))
+{
+    DIR_ITEM *this;
+
+    if (dir_list == NULL)
+       return;
+    do
+    {
+       this = dir_list;
+       dir_list = dir_list->next;
+       amfree(this);
+    } while (dir_list != NULL);
+}
+
+/* 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;
+{
+    DIR_ITEM *last;
+
+    dbprintf(("add_dir_list_item: Adding \"%s\" \"%d\" \"%s\" \"%d\" \"%s\"\n",
+             date, level, tape, fileno, path));
+
+    if (dir_list == NULL)
+    {
+       dir_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       dir_list->next = NULL;
+       strncpy(dir_list->date, date, sizeof(dir_list->date)-1);
+       dir_list->date[sizeof(dir_list->date)-1] = '\0';
+       dir_list->level = level;
+       strncpy(dir_list->tape, tape, sizeof(dir_list->tape)-1);
+       dir_list->tape[sizeof(dir_list->tape)-1] = '\0';
+       dir_list->fileno = fileno;
+       strncpy(dir_list->path, path, sizeof(dir_list->path)-1);
+       dir_list->path[sizeof(dir_list->path)-1] = '\0';
+
+       return 0;
+    }
+
+    last = dir_list;
+    while (last->next != NULL)
+    {
+       last = last->next;
+    }
+
+    last->next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+    last->next->next = NULL;
+    strncpy(last->next->date, date, sizeof(last->next->date)-1);
+    last->next->date[sizeof(last->next->date)-1] = '\0';
+    last->next->level = level;
+    strncpy(last->next->tape, tape, sizeof(last->next->tape)-1);
+    last->next->tape[sizeof(last->next->tape)-1] = '\0';
+    last->next->fileno = fileno;
+    strncpy(last->next->path, path, sizeof(last->next->path)-1);
+    last->next->path[sizeof(last->next->path)-1] = '\0';
+
+    return 0;
+}
+
+
+void list_disk_history P((void))
+{
+    if (converse("DHST") == -1)
+       exit(1);
+}
+
+
+void suck_dir_list_from_server P((void))
+{
+    char *cmd = NULL;
+    char *err = NULL;
+    int i;
+    char *l = NULL;
+    char *date, *date_undo, date_undo_ch = '\0';
+    int level, fileno;
+    char *tape, *tape_undo, tape_undo_ch = '\0';
+    char *dir, *dir_undo, dir_undo_ch = '\0';
+    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);
+    date_undo = tape_undo = dir_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;
+               if(dir_undo) *dir_undo = dir_undo_ch;
+               date_undo = 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())
+       {
+           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);
+       date_undo = s - 1;
+       date_undo_ch = *date_undo;
+       *date_undo = '\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(their_features, fe_amindexd_fileno_in_OLSD)) {
+           skip_whitespace(s, ch);
+           if(ch == '\0' || sscanf(s - 1, "%d", &fileno) != 1) {
+               err = "bad reply: cannot parse fileno field";
+               continue;
+           }
+           skip_integer(s, ch);
+       }
+       else {
+           fileno = -1;
+       }
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           err = "bad reply: missing directory field";
+           continue;
+       }
+       dir = s - 1;
+
+       /* 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;
+       }
+       add_dir_list_item(date, level, tape, fileno, dir);
+    }
+    amfree(disk_path_slash_dot);
+    amfree(disk_path_slash);
+    if(!server_happy()) {
+       puts(reply_line());
+    } else if(err) {
+       if(*err) {
+           puts(err);
+       }
+       puts(cmd);
+       clear_dir_list();
+    }
+    amfree(cmd);
+}
+
+
+void list_directory P((void))
+{
+    size_t i;
+    DIR_ITEM *item;
+    FILE *fp;
+    char *pager;
+    char *pager_command;
+
+    if (disk_path == NULL) {
+       printf("Must select a disk before listing files\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))
+       fprintf(fp, "%s %s\n", item->date, item->path+i);
+    apclose(fp);
+}
diff --git a/recover-src/extract_list.c b/recover-src/extract_list.c
new file mode 100644 (file)
index 0000000..a38eec9
--- /dev/null
@@ -0,0 +1,1754 @@
+/*
+ * 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.43.2.13.4.6.2.19 2003/03/04 21:13:58 martinea 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"
+#ifdef SAMBA_CLIENT
+#include "findpass.h"
+#endif
+
+#if defined(KRB4_SECURITY)
+#include "krb4-security.h"
+#endif
+#include "util.h"
+
+typedef struct EXTRACT_LIST_ITEM
+{
+    char path[1024];
+
+    struct EXTRACT_LIST_ITEM *next;
+}
+EXTRACT_LIST_ITEM;
+
+typedef struct EXTRACT_LIST
+{
+    char date[11];                     /* date tape created */
+    int  level;                                /* level of dump */
+    char tape[256];                    /* tape label */
+    int 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;
+
+#ifdef SAMBA_CLIENT
+unsigned short samba_extract_method = SAMBA_TAR;
+#endif /* SAMBA_CLIENT */
+
+#define READ_TIMEOUT   240*60
+
+static int okay_to_continue P((int, int,  int));
+
+ssize_t read_buffer(datafd, buffer, buflen)
+int datafd;
+char *buffer;
+size_t buflen;
+{
+    int maxfd, nfound = 0;
+    ssize_t size = 0;
+    fd_set readset, selectset;
+    struct timeval timeout;
+    char *dataptr;
+    size_t spaceleft;
+    int eof;
+
+    if(datafd < 0 || datafd >= FD_SETSIZE) {
+       errno = EMFILE;                                 /* out of range */
+       return -1;
+    }
+
+    dataptr = buffer;
+    spaceleft = buflen;
+
+    maxfd = datafd + 1;
+    eof = 0;
+
+    FD_ZERO(&readset);
+    FD_SET(datafd, &readset);
+
+    do {
+
+       timeout.tv_sec = READ_TIMEOUT;
+       timeout.tv_usec = 0;
+       memcpy(&selectset, &readset, sizeof(fd_set));
+
+       nfound = select(maxfd, (SELECT_ARG_TYPE *)(&selectset), NULL, NULL, &timeout);
+
+       /* check for errors or timeout */
+
+       if(nfound == 0)  {
+           size=-2;
+           fprintf(stderr,"timeout waiting for amrestore\n");
+           fprintf(stderr,"increase READ_TIMEOUT in recover-src/extract_list.c if your tape is slow\n");
+       }
+       if(nfound == -1) {
+           size=-3;
+           fprintf(stderr,"nfound == -1\n");
+       }
+
+       /* read any data */
+
+       if(FD_ISSET(datafd, &selectset)) {
+           size = read(datafd, dataptr, spaceleft);
+           switch(size) {
+           case -1:
+               break;
+           case 0:
+               spaceleft -= size;
+               dataptr += size;
+               fprintf(stderr,
+                       "EOF, check amidxtaped.<timestamp>.debug file on %s.\n",
+                       tape_server_name);
+               break;
+           default:
+               spaceleft -= size;
+               dataptr += size;
+               break;
+           }
+       }
+    } while (spaceleft>0 && size>0);
+
+    if(size<0) {
+       return -1;
+    }
+    return (ssize_t)(buflen-spaceleft);
+}
+
+EXTRACT_LIST *first_tape_list P((void))
+{
+    return extract_list;
+}
+
+EXTRACT_LIST *next_tape_list(list)
+EXTRACT_LIST *list;
+{
+    if (list == NULL)
+       return NULL;
+    return list->next;
+}
+
+static void clear_tape_list(tape_list)
+EXTRACT_LIST *tape_list;
+{
+    EXTRACT_LIST_ITEM *this, *next;
+
+    this = tape_list->files;
+    while (this != NULL)
+    {
+       next = this->next;
+       free(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(tape_list)
+EXTRACT_LIST *tape_list;
+{
+    EXTRACT_LIST *this, *prev;
+
+    /* is it first on the list? */
+    if (tape_list == extract_list)
+    {
+       clear_tape_list(tape_list);
+       extract_list = tape_list->next;
+       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)
+       {
+           clear_tape_list(tape_list);
+           prev->next = tape_list->next;
+           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(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 P((void))
+{
+    while (extract_list != NULL)
+       delete_tape_list(extract_list);
+}
+
+
+/* returns -1 if error */
+/* returns  0 on succes */
+/* returns  1 if already added */
+static int add_extract_item(ditem)
+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));
+           strncpy(that->path, ditem_path, sizeof(that->path)-1);
+           that->path[sizeof(that->path)-1] = '\0';
+           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));
+    strncpy(this->tape, ditem->tape, sizeof(this->tape)-1);
+    this->tape[sizeof(this->tape)-1] ='\0';
+    this->level = ditem->level;
+    this->fileno = ditem->fileno;
+    strncpy(this->date, ditem->date, sizeof(this->date)-1);
+    this->date[sizeof(this->date)-1] = '\0';
+    that = (EXTRACT_LIST_ITEM *)alloc(sizeof(EXTRACT_LIST_ITEM));
+    strncpy(that->path, ditem_path, sizeof(that->path)-1);
+    that->path[sizeof(that->path)-1] = '\0';
+    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(ditem)
+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);
+               /* 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);
+                   amfree(ditem_path);
+                   return 0;
+               }
+               prev = that;
+               that = that->next;
+           }
+           amfree(ditem_path);
+           return 1;
+       }
+    }
+
+    amfree(ditem_path);
+    return 1;
+}
+
+
+void add_glob(glob)
+char *glob;
+{
+    char *regex;
+    char *regex_path;
+    char *s;
+
+    regex = glob_to_regex(glob);
+    dbprintf(("add_glob (%s) -> %s\n", glob, regex));
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+       puts(s);
+       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 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);
+}
+
+void add_regex(regex)
+char *regex;
+{
+    char *s;
+
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("\"%s\" is not a valid regular expression: ", regex);
+       puts(s);
+       return;
+    }
+    add_file(regex, regex);
+}
+
+void add_file(path, regex)
+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;
+    int j;
+    char *dir, *dir_undo, dir_undo_ch = '\0';
+    char *ditem_path = NULL;
+    char *l = NULL;
+    int  added;
+    char *s, *fp;
+    int ch;
+    int found_one;
+
+    if (disk_path == NULL) {
+       printf("Must select directory before adding files\n");
+       return;
+    }
+
+    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';
+
+    /* 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);
+    }
+
+    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;
+    for (ditem=get_dir_list(); ditem!=NULL; ditem=get_next_dir_item(ditem))
+    {
+       dbprintf(("add_file: Pondering ditem->path=\"%s\"\n", ditem->path));
+       if (match(path_on_disk, ditem->path)
+           || match(path_on_disk_slash, ditem->path))
+       {
+           found_one = 1;
+           j = 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;
+               }
+               amfree(err);
+               dir_undo = NULL;
+               added=0;
+               strncpy(lditem.path, ditem_path, sizeof(lditem.path)-1);
+               lditem.path[sizeof(lditem.path)-1] = '\0';
+               /* 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;
+                   }
+                   copy_string(s, ch, lditem.date, sizeof(lditem.date), fp);
+                   if(fp == NULL) {
+                       err = "bad reply: date field too large";
+                       continue;
+                   }
+
+                   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;
+                   }
+                   copy_string(s, ch, lditem.tape, sizeof(lditem.tape), fp);
+                   if(fp == NULL) {
+                       err = "bad reply: tape field too large";
+                       continue;
+                   }
+
+                   if(am_has_feature(their_features, fe_amindexd_fileno_in_ORLD)) {
+                       skip_whitespace(s, ch);
+                       if(ch == '\0' || sscanf(s - 1, "%d", &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_non_whitespace(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:
+                       printf("Added dir %s at date %s\n",
+                              ditem_path, lditem.date);
+                       dbprintf(("add_file: (Successful) Added dir %s at date %s\n",
+                                 ditem_path,lditem.date));
+                       added=1;
+                       break;
+                   case  1:
+                       break;
+                   }
+               }
+               if(!server_happy()) {
+                   puts(reply_line());
+               } else if(err) {
+                   if(*err) {
+                       puts(err);
+                   }
+                   puts(cmd);
+               } else if(added == 0) {
+                   printf("dir %s already added\n", ditem_path);
+                   dbprintf(("add_file: dir %s already added\n", ditem_path));
+               }
+           }
+           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:
+                   printf("Added %s\n", ditem->path);
+                   dbprintf(("add_file: (Successful) Added %s\n",
+                             ditem->path));
+                   break;
+               case  1:
+                   printf("File %s already added\n", ditem->path);
+                   dbprintf(("add_file: file %s already added\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(("add_file: (Failed) File %s doesn't exist in directory\n",
+                 path));
+    }
+}
+
+
+void delete_glob(glob)
+char *glob;
+{
+    char *regex;
+    char *regex_path;
+    char *s;
+
+    regex = glob_to_regex(glob);
+    dbprintf(("delete_glob (%s) -> %s\n", glob, regex));
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("\"%s\" is not a valid shell wildcard pattern: ", glob);
+       puts(s);
+       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 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);
+}
+
+void delete_regex(regex)
+char *regex;
+{
+    char *s;
+
+    if ((s = validate_regexp(regex)) != NULL) {
+       printf("\"%s\" is not a valid regular expression: ", regex);
+       puts(s);
+       return;
+    }
+    delete_file(regex, regex);
+}
+
+void delete_file(path, regex)
+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;
+    int j;
+    char *date, *date_undo, date_undo_ch = '\0';
+    char *tape, *tape_undo, tape_undo_ch = '\0';
+    char *dir, *dir_undo, dir_undo_ch = '\0';
+    int  level, fileno;
+    char *ditem_path = NULL;
+    char *l = NULL;
+    int  deleted;
+    char *s;
+    int ch;
+    int found_one;
+
+    if (disk_path == NULL) {
+       printf("Must select directory before deleting files\n");
+       return;
+    }
+
+    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';
+
+    /* 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);
+    }
+
+    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))
+    {
+       dbprintf(("delete_file: Pondering ditem->path=\"%s\"\n", ditem->path));
+       if (match(path_on_disk, ditem->path)
+           || match(path_on_disk_slash, ditem->path))
+       {
+           found_one = 1;
+           j = 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;
+               strncpy(lditem.path, ditem->path, sizeof(lditem.path)-1);
+               lditem.path[sizeof(lditem.path)-1] = '\0';
+               amfree(cmd);
+               amfree(err);
+               date_undo = 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;
+                           date_undo = 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);
+                   date_undo = s - 1;
+                   date_undo_ch = *date_undo;
+                   *date_undo = '\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(their_features, fe_amindexd_fileno_in_ORLD)) {
+                       skip_whitespace(s, ch);
+                       if(ch == '\0' || sscanf(s - 1, "%d", &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_non_whitespace(s, ch);
+                   dir_undo = s - 1;
+                   dir_undo_ch = *dir_undo;
+                   *dir_undo = '\0';
+
+                   strncpy(lditem.date, date, sizeof(lditem.date)-1);
+                   lditem.date[sizeof(lditem.date)-1] = '\0';
+                   lditem.level=level;
+                   strncpy(lditem.tape, tape, sizeof(lditem.tape)-1);
+                   lditem.tape[sizeof(lditem.tape)-1] = '\0';
+                   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);
+                   }
+                   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(file)
+char *file;
+{
+    EXTRACT_LIST *this;
+    EXTRACT_LIST_ITEM *that;
+    FILE *fp;
+    char *pager;
+    char *pager_command;
+
+    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
+    {
+       if ((fp = fopen(file, "w")) == NULL)
+       {
+           printf("Can't open file '%s' to print extract list into\n", file);
+           return;
+       }
+    }
+
+    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 P((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(allow_tape, allow_skip, allow_retry)
+    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)) {}
+       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;
+       }
+    }
+    amfree(line);
+    return ret;
+}
+
+static void send_to_tape_server(tss, cmd)
+int tss;
+char *cmd;
+{
+    size_t l, n;
+    ssize_t s;
+    char *end;
+
+    for (l = 0, n = strlen(cmd); l < n; l += s)
+       if ((s = write(tss, cmd + l, n - l)) < 0)
+       {
+           perror("Error writing to tape server");
+           exit(101);
+       }
+    end = "\r\n";
+    for (l = 0, n = strlen(end); l < n; l += s)
+       if ((s = write(tss, end + l, n - l)) < 0)
+       {
+           perror("Error writing to tape server");
+           exit(101);
+       }
+}
+
+
+/* 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;
+{
+    struct servent *sp;
+    int my_port;
+    int tape_server_socket;
+    char *disk_regex = NULL;
+    char *host_regex = NULL;
+    char *service_name = NULL;
+    char *line = NULL;
+    char *clean_datestamp, *ch, *ch1;
+
+    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_server_socket = stream_client_privileged(tape_server_name,
+                                                 ntohs(sp->s_port),
+                                                 -1,
+                                                 STREAM_BUFSIZE,
+                                                 &my_port);
+    if (tape_server_socket < 0)
+    {
+       printf("cannot connect to %s: %s\n", tape_server_name, strerror(errno));
+       return -1;
+    }
+    if (my_port >= IPPORT_RESERVED) {
+       aclose(tape_server_socket);
+       printf("did not get a reserved port: %d\n", my_port);
+       return -1;
+    }
+    setegid(getgid());
+    seteuid(getuid());                         /* put it back */
+
+    /* do the security thing */
+#if defined(KRB4_SECURITY)
+#if 0 /* not yet implemented */
+    if(krb4_auth)
+    {
+       line = get_krb_security();
+    }
+#endif /* 0 */
+#endif
+    {
+       line = get_bsd_security();
+    }
+    send_to_tape_server(tape_server_socket, 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';
+
+    if(am_has_feature(their_features, fe_amidxtaped_header) &&
+       am_has_feature(their_features, fe_amidxtaped_device) &&
+       am_has_feature(their_features, fe_amidxtaped_host) &&
+       am_has_feature(their_features, fe_amidxtaped_disk) &&
+       am_has_feature(their_features, fe_amidxtaped_datestamp)) {
+
+       char *tt = NULL;
+
+       if(am_has_feature(their_features, fe_amidxtaped_config)) {
+           tt = newstralloc2(tt, "CONFIG=", config);
+           send_to_tape_server(tape_server_socket, tt);
+       }
+       if(am_has_feature(their_features, fe_amidxtaped_label) &&
+          label && label[0] != '/') {
+           tt = newstralloc2(tt,"LABEL=",label);
+           send_to_tape_server(tape_server_socket, tt);
+       }
+       if(am_has_feature(their_features, fe_amidxtaped_fsf)) {
+           char v_fsf[100];
+           ap_snprintf(v_fsf, 99, "%d", fsf);
+           tt = newstralloc2(tt, "FSF=",v_fsf);
+           send_to_tape_server(tape_server_socket, tt);
+       }
+       send_to_tape_server(tape_server_socket, "HEADER");
+       tt = newstralloc2(tt, "DEVICE=", dump_device_name);
+       send_to_tape_server(tape_server_socket, tt);
+       tt = newstralloc2(tt, "HOST=", host_regex);
+       send_to_tape_server(tape_server_socket, tt);
+       tt = newstralloc2(tt, "DISK=", disk_regex);
+       send_to_tape_server(tape_server_socket, tt);
+       tt = newstralloc2(tt, "DATESTAMP=", clean_datestamp);
+       send_to_tape_server(tape_server_socket, tt);
+       send_to_tape_server(tape_server_socket, "END");
+       amfree(tt);
+    }
+    else if(1 /* am_has_feature(their_features, fe_amidxtaped_nargs) */) {
+       /* 2.4.3 doesn't set fe_amidxtaped_nargs but support it */
+       /* must be supported without test until 2005 */
+
+       /* send to the tape server what tape file we want */
+       /* 6 args:
+        *   "-h"
+        *   "-p"
+        *   "tape device"
+        *   "hostname"
+        *   "diskname"
+        *   "datestamp"
+        */
+       send_to_tape_server(tape_server_socket, "6");
+       send_to_tape_server(tape_server_socket, "-h");
+       send_to_tape_server(tape_server_socket, "-p");
+       send_to_tape_server(tape_server_socket, dump_device_name);
+       send_to_tape_server(tape_server_socket, host_regex);
+       send_to_tape_server(tape_server_socket, disk_regex);
+       send_to_tape_server(tape_server_socket, clean_datestamp);
+
+       dbprintf(("Started amidxtaped with arguments \"6 -h -p %s %s %s %s\"\n",
+                 dump_device_name, host_regex, disk_regex, clean_datestamp));
+    }
+
+    amfree(disk_regex);
+    amfree(host_regex);
+    amfree(clean_datestamp);
+
+    return tape_server_socket;
+}
+
+
+size_t 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.
+ */
+{
+    ssize_t bytes_read;
+    bytes_read=read_buffer(tapedev,buffer,buflen);
+    if(bytes_read < 0) {
+       error("error reading tape: %s", strerror(errno));
+    }
+    else 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");
+    }
+    else { /* bytes_read == buflen */
+       parse_file_header(buffer, file, bytes_read);
+    }
+    return((size_t)bytes_read);
+}
+
+enum dumptypes {IS_UNKNOWN, IS_DUMP, IS_GNUTAR, IS_TAR, IS_SAMBA, IS_SAMBA_TAR};
+
+/* exec restore to do the actual restoration */
+static void extract_files_child(in_fd, elist)
+    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 buflen;
+    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)
+    {
+       perror("extract_list - extract files client");
+       exit(1);
+    }
+
+    /* read the file header */
+    fh_init(&file);
+    buflen=read_file_header(buffer, &file, sizeof(buffer), STDIN_FILENO);
+
+    if(buflen == 0 || file.type != F_DUMPFILE) {
+       print_header(stdout, &file);
+       error("bad header");
+    }
+
+    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:
+    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((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("-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:
+           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 */
+}
+
+
+/* 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))
+{
+    EXTRACT_LIST *elist;
+    pid_t pid;
+    amwait_t child_stat;
+    char buf[STR_SIZE];
+    char *l;
+    int tape_server_socket;
+    int first;
+    int otc;
+
+    if (!is_extract_list_nonempty())
+    {
+       printf("Extract list empty - No files to extract!\n");
+       return;
+    }
+
+    /* 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("                               ");
+           printf(" %s\n", elist->tape);
+       }
+    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("                               ");
+           printf(" %s\n", elist->tape);
+       }
+    printf("\n");
+    getcwd(buf, sizeof(buf));
+    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 %s\n",dump_device_name);
+       }
+       else {
+           printf("Extracting files using tape drive %s on host %s.\n",
+                  tape_device_name, tape_server_name);
+           printf("Load tape %s now\n", elist->tape);
+           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_server_socket = 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 */
+           extract_files_child(tape_server_socket, elist);
+           /*NOT REACHED*/
+       }
+       /* this is the parent */
+       if (pid == -1)
+       {
+           perror("extract_list - error forking child");
+           exit(1);
+       }
+
+       /* store the child pid globally so that it can be killed on intr */
+       extract_restore_child_pid = pid;
+
+       aclose(tape_server_socket);
+
+       /* 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 (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;
+           else if(otc == 1) {
+               delete_tape_list(elist); /* tape failed so delete from list */
+           }
+           else { /* RETRY_TAPE */
+           }
+       }
+       else {
+           delete_tape_list(elist);    /* tape done so delete from list */
+       }
+    }
+}
diff --git a/recover-src/help.c b/recover-src/help.c
new file mode 100644 (file)
index 0000000..92d3faa
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.4.4.2.4.1.2.1 2002/03/06 19:23:32 martinea Exp $
+ *
+ * implements the "help" command in amrecover
+ */
+
+#include "amrecover.h"
+
+/* print a list of valid commands */
+void help_list P((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("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("\n");
+}
diff --git a/recover-src/set_commands.c b/recover-src/set_commands.c
new file mode 100644 (file)
index 0000000..21603ab
--- /dev/null
@@ -0,0 +1,569 @@
+/*
+ * 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.11.2.3.4.2.2.7 2004/02/11 13:15:29 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(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(host)
+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 set_disk(dsk, mtpt)
+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(amdevice)
+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(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(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(path_on_disk, default_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,'/');
+               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(dir)
+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;
+    }
+
+    if (disk_name == NULL) {
+       printf("Must select disk before setting directory\n");
+       return;
+    }
+
+    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;
+           }
+           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);
+               amfree(new_dir);
+               amfree(ldir);
+               return;
+           }
+           de = strrchr(new_dir, '/'); /* always at least 1 */
+           if (de == new_dir)
+           {
+               /* at top of disk */
+               *(de+1) = '\0';
+           }
+           else
+           {
+               *de = '\0';
+           }
+       } else {
+           if (strcmp(new_dir, "/") != 0) {
+               strappend(new_dir, "/");
+           }
+           strappend(new_dir, ldir);
+       }
+    }
+
+    cmd = stralloc2("OISD ", new_dir);
+    if (exchange(cmd) == -1)
+       exit(1);
+    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);
+    }
+
+    amfree(new_dir);
+    amfree(ldir);
+}
+
+
+/* prints the current working directory */
+void show_directory P((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 (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 (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;
+    }
+  }
+#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/recover-src/uparse.c b/recover-src/uparse.c
new file mode 100644 (file)
index 0000000..3d97a0d
--- /dev/null
@@ -0,0 +1,1324 @@
+/* A Bison parser, made from uparse.y
+   by GNU bison 1.35.  */
+
+#define YYBISON 1  /* Identify Bison output.  */
+
+# define       LISTDISK        257
+# define       SETHOST 258
+# define       SETDISK 259
+# define       SETDATE 260
+# define       SETTAPE 261
+# define       SETMODE 262
+# define       CD      263
+# define       CDX     264
+# define       QUIT    265
+# define       DHIST   266
+# define       LS      267
+# define       ADD     268
+# define       ADDX    269
+# define       EXTRACT 270
+# define       LIST    271
+# define       DELETE  272
+# define       DELETEX 273
+# define       PWD     274
+# define       CLEAR   275
+# define       HELP    276
+# define       LCD     277
+# define       LPWD    278
+# define       MODE    279
+# define       SMB     280
+# define       TAR     281
+# define       PATH    282
+# define       DATE    283
+
+#line 31 "uparse.y"
+
+#include "amanda.h"
+#include "amrecover.h"
+
+void yyerror P((char *s));
+extern int yylex P((void));
+
+#line 40 "uparse.y"
+#ifndef YYSTYPE
+typedef union {
+  int intval;
+  double floatval;
+  char *strval;
+  int subtok;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+
+
+#define        YYFINAL         60
+#define        YYFLAG          -32768
+#define        YYNTBASE        30
+
+/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
+#define YYTRANSLATE(x) ((unsigned)(x) <= 283 ? yytranslate[x] : 45)
+
+/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
+static const 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,     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
+};
+
+#if YYDEBUG
+static const short yyprhs[] =
+{
+       0,     0,     2,     4,     6,     8,    10,    12,    14,    16,
+      18,    20,    23,    25,    28,    31,    35,    38,    41,    43,
+      46,    49,    52,    55,    57,    59,    62,    64,    66,    68,
+      70,    72,    75,    78,    80,    83,    86,    88,    91,    94,
+      96,    99,   102,   104,   106,   109,   111
+};
+static const short yyrhs[] =
+{
+      31,     0,    32,     0,    33,     0,    34,     0,    36,     0,
+      38,     0,    40,     0,    42,     0,    43,     0,    44,     0,
+       3,    28,     0,     3,     0,     6,    29,     0,     4,    28,
+       0,     5,    28,    28,     0,     5,    28,     0,     7,    28,
+       0,     7,     0,     9,    28,     0,    10,    28,     0,     8,
+      26,     0,     8,    27,     0,    12,     0,    13,     0,    17,
+      28,     0,    17,     0,    20,     0,    21,     0,    25,     0,
+      11,     0,    14,    35,     0,    35,    28,     0,    28,     0,
+      15,    37,     0,    37,    28,     0,    28,     0,    18,    39,
+       0,    39,    28,     0,    28,     0,    19,    41,     0,    41,
+      28,     0,    28,     0,    24,     0,    23,    28,     0,    22,
+       0,    16,     0
+};
+
+#endif
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const short yyrline[] =
+{
+       0,    62,    64,    65,    66,    67,    68,    69,    70,    71,
+      72,    75,    77,    78,    79,    80,    81,    82,    83,    84,
+      85,    86,    91,    98,   100,   101,   102,   103,   104,   105,
+     108,   112,   116,   118,   121,   125,   127,   130,   134,   136,
+     139,   143,   145,   148,   150,   158,   162
+};
+#endif
+
+
+#if (YYDEBUG) || defined YYERROR_VERBOSE
+
+/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
+static const char *const yytname[] =
+{
+  "$", "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", "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
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const short yyr1[] =
+{
+       0,    30,    30,    30,    30,    30,    30,    30,    30,    30,
+      30,    31,    31,    31,    31,    31,    31,    31,    31,    31,
+      31,    31,    31,    32,    32,    32,    32,    32,    32,    32,
+      33,    34,    35,    35,    36,    37,    37,    38,    39,    39,
+      40,    41,    41,    42,    42,    43,    44
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const short yyr2[] =
+{
+       0,     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
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+   doesn't specify something else to do.  Zero means the default is an
+   error. */
+static const short yydefact[] =
+{
+       0,    12,     0,     0,     0,    18,     0,     0,     0,    30,
+      23,    24,     0,     0,    46,    26,     0,     0,    27,    28,
+      45,     0,    43,    29,     1,     2,     3,     4,     5,     6,
+       7,     8,     9,    10,    11,    14,    16,    13,    17,    21,
+      22,    19,    20,    33,    31,    36,    34,    25,    39,    37,
+      42,    40,    44,    15,    32,    35,    38,    41,     0,     0,
+       0
+};
+
+static const short yydefgoto[] =
+{
+      58,    24,    25,    26,    27,    44,    28,    46,    29,    49,
+      30,    51,    31,    32,    33
+};
+
+static const short yypact[] =
+{
+      -3,    -5,    -1,     0,     1,     3,    -2,     4,     5,-32768,
+  -32768,-32768,     6,     7,-32768,     8,     9,    10,-32768,-32768,
+  -32768,    11,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768,-32768,    12,-32768,-32768,-32768,
+  -32768,-32768,-32768,-32768,    13,-32768,    14,-32768,-32768,    15,
+  -32768,    16,-32768,-32768,-32768,-32768,-32768,-32768,    26,    29,
+  -32768
+};
+
+static const short yypgoto[] =
+{
+  -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+  -32768,-32768,-32768,-32768,-32768
+};
+
+
+#define        YYLAST          44
+
+
+static const short yytable[] =
+{
+       1,     2,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    34,    39,    40,    59,    35,    36,    60,
+      37,    38,    41,    42,    43,    45,    47,    48,    50,    52,
+      53,    54,    55,    56,    57
+};
+
+static const short 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,     0,
+      29,    28,    28,    28,    28,    28,    28,    28,    28,    28,
+      28,    28,    28,    28,    28
+};
+/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
+#line 3 "/usr/share/bison/bison.simple"
+
+/* Skeleton output parser for bison,
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* 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.  */
+
+/* This is the parser code that is written into each bison parser when
+   the %semantic_parser declaration is not specified in the grammar.
+   It was written by Richard Stallman by simplifying the hairy parser
+   used when %semantic_parser is specified.  */
+
+/* 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.  */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# if YYSTACK_USE_ALLOCA
+#  define YYSTACK_ALLOC alloca
+# else
+#  ifndef YYSTACK_USE_ALLOCA
+#   if defined (alloca) || defined (_ALLOCA_H)
+#    define YYSTACK_ALLOC alloca
+#   else
+#    ifdef __GNUC__
+#     define YYSTACK_ALLOC __builtin_alloca
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC malloc
+#  define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+        || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short yyss;
+  YYSTYPE yyvs;
+# if YYLSP_NEEDED
+  YYLTYPE yyls;
+# endif
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# if YYLSP_NEEDED
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE))     \
+      + 2 * YYSTACK_GAP_MAX)
+# else
+#  define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))                                \
+      + YYSTACK_GAP_MAX)
+# endif
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         register 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_MAX;   \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (0)
+
+#endif
+
+
+#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)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#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 yyerrlab1
+/* 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);                                                \
+      yychar1 = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK;                                              \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror ("syntax error: cannot back up");                        \
+      YYERROR;                                                 \
+    }                                                          \
+while (0)
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+   are run).
+
+   When YYLLOC_DEFAULT is run, CURRENT is set the location of the
+   first token.  By default, to implement support for ranges, extend
+   its range to the last symbol.  */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)               \
+   Current.last_line   = Rhs[N].last_line;     \
+   Current.last_column = Rhs[N].last_column;
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#if YYPURE
+# if YYLSP_NEEDED
+#  ifdef YYLEX_PARAM
+#   define YYLEX               yylex (&yylval, &yylloc, YYLEX_PARAM)
+#  else
+#   define YYLEX               yylex (&yylval, &yylloc)
+#  endif
+# else /* !YYLSP_NEEDED */
+#  ifdef YYLEX_PARAM
+#   define YYLEX               yylex (&yylval, YYLEX_PARAM)
+#  else
+#   define YYLEX               yylex (&yylval)
+#  endif
+# endif /* !YYLSP_NEEDED */
+#else /* !YYPURE */
+# define YYLEX                 yylex ()
+#endif /* !YYPURE */
+
+
+/* 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)
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+#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
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+\f
+#ifdef 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
+{
+  register 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
+{
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+#endif
+\f
+#line 315 "/usr/share/bison/bison.simple"
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+   into yyparse.  The argument should have type void *.
+   It should actually point to an object.
+   Grammar actions can access the variable by casting it
+   to the proper pointer type.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+#  define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL
+# else
+#  define YYPARSE_PARAM_ARG YYPARSE_PARAM
+#  define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes.  */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
+   variables are global, or local to YYPARSE.  */
+
+#define YY_DECL_NON_LSP_VARIABLES                      \
+/* The lookahead symbol.  */                           \
+int yychar;                                            \
+                                                       \
+/* The semantic value of the lookahead symbol. */      \
+YYSTYPE yylval;                                                \
+                                                       \
+/* Number of parse errors so far.  */                  \
+int yynerrs;
+
+#if YYLSP_NEEDED
+# define YY_DECL_VARIABLES                     \
+YY_DECL_NON_LSP_VARIABLES                      \
+                                               \
+/* Location data for the lookahead symbol.  */ \
+YYLTYPE yylloc;
+#else
+# define YY_DECL_VARIABLES                     \
+YY_DECL_NON_LSP_VARIABLES
+#endif
+
+
+/* If nonreentrant, generate the variables here. */
+
+#if !YYPURE
+YY_DECL_VARIABLES
+#endif  /* !YYPURE */
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+     YYPARSE_PARAM_DECL
+{
+  /* If reentrant, generate the variables here. */
+#if YYPURE
+  YY_DECL_VARIABLES
+#endif  /* !YYPURE */
+
+  register int yystate;
+  register int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yychar1 = 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        yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  register YYSTYPE *yyvsp;
+
+#if YYLSP_NEEDED
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+#endif
+
+#if YYLSP_NEEDED
+# define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+#else
+# define YYPOPSTACK   (yyvsp--, yyssp--)
+#endif
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+#if YYLSP_NEEDED
+  YYLTYPE yyloc;
+#endif
+
+  /* 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;
+#if YYLSP_NEEDED
+  yylsp = yyls;
+#endif
+  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 (yyssp >= yyss + yystacksize - 1)
+    {
+      /* 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 *yyss1 = yyss;
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  */
+# if YYLSP_NEEDED
+       YYLTYPE *yyls1 = yyls;
+       /* This used to be a conditional around just the two extra args,
+          but that might be undefined if yyoverflow is a macro.  */
+       yyoverflow ("parser stack overflow",
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+                   &yyls1, yysize * sizeof (*yylsp),
+                   &yystacksize);
+       yyls = yyls1;
+# else
+       yyoverflow ("parser stack overflow",
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+                   &yystacksize);
+# endif
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
+      /* Extend the stack our own way.  */
+      if (yystacksize >= YYMAXDEPTH)
+       goto yyoverflowlab;
+      yystacksize *= 2;
+      if (yystacksize > YYMAXDEPTH)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       short *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyoverflowlab;
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+# if YYLSP_NEEDED
+       YYSTACK_RELOCATE (yyls);
+# endif
+# undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+#if YYLSP_NEEDED
+      yylsp = yyls + yysize - 1;
+#endif
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyssp >= yyss + yystacksize - 1)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a lookahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* yychar is either YYEMPTY or YYEOF
+     or a valid token in external form.  */
+
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  /* Convert token to internal form (in yychar1) for indexing tables with */
+
+  if (yychar <= 0)             /* This means end of input. */
+    {
+      yychar1 = 0;
+      yychar = YYEOF;          /* Don't call YYLEX any more */
+
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yychar1 = YYTRANSLATE (yychar);
+
+#if YYDEBUG
+     /* We have to keep this `#if YYDEBUG', since we use variables
+       which are defined only if `YYDEBUG' is set.  */
+      if (yydebug)
+       {
+         YYFPRINTF (stderr, "Next token is %d (%s",
+                    yychar, yytname[yychar1]);
+         /* Give the individual parser a way to print the precise
+            meaning of a token, for further debugging info.  */
+# ifdef YYPRINT
+         YYPRINT (stderr, yychar, yylval);
+# endif
+         YYFPRINTF (stderr, ")\n");
+       }
+#endif
+    }
+
+  yyn += yychar1;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+    goto yydefault;
+
+  yyn = yytable[yyn];
+
+  /* yyn is what to do for this token type in this state.
+     Negative => reduce, -yyn is rule number.
+     Positive => shift, yyn is new state.
+       New state is final state => don't bother to shift,
+       just return success.
+     0, or most negative number => error.  */
+
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrlab;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the lookahead token.  */
+  YYDPRINTF ((stderr, "Shifting token %d (%s), ",
+             yychar, yytname[yychar1]));
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+#if YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  /* 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 the semantic value of
+     the lookahead token.  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];
+
+#if YYLSP_NEEDED
+  /* Similarly for the default location.  Let the user run additional
+     commands if for instance locations are ranges.  */
+  yyloc = yylsp[1-yylen];
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+#endif
+
+#if YYDEBUG
+  /* We have to keep this `#if YYDEBUG', since we use variables which
+     are defined only if `YYDEBUG' is set.  */
+  if (yydebug)
+    {
+      int yyi;
+
+      YYFPRINTF (stderr, "Reducing via rule %d (line %d), ",
+                yyn, yyrline[yyn]);
+
+      /* Print the symbols being reduced, and their result.  */
+      for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++)
+       YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+      YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]);
+    }
+#endif
+
+  switch (yyn) {
+
+case 11:
+#line 76 "uparse.y"
+{ list_disk(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 12:
+#line 77 "uparse.y"
+{ list_disk(NULL); }
+    break;
+case 13:
+#line 78 "uparse.y"
+{ set_date(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 14:
+#line 79 "uparse.y"
+{ set_host(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 15:
+#line 80 "uparse.y"
+{ set_disk(yyvsp[-1].strval, yyvsp[0].strval); amfree(yyvsp[-1].strval); amfree(yyvsp[0].strval); }
+    break;
+case 16:
+#line 81 "uparse.y"
+{ set_disk(yyvsp[0].strval, NULL); amfree(yyvsp[0].strval); }
+    break;
+case 17:
+#line 82 "uparse.y"
+{ set_tape(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 18:
+#line 83 "uparse.y"
+{ set_tape(""); }
+    break;
+case 19:
+#line 84 "uparse.y"
+{ cd_glob(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 20:
+#line 85 "uparse.y"
+{ cd_regex(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 21:
+#line 86 "uparse.y"
+{
+#ifdef SAMBA_CLIENT
+                        set_mode(SAMBA_SMBCLIENT);
+#endif /* SAMBA_CLIENT */
+                    }
+    break;
+case 22:
+#line 91 "uparse.y"
+{
+#ifdef SAMBA_CLIENT
+                        set_mode(SAMBA_TAR);
+#endif /* SAMBA_CLIENT */
+                    }
+    break;
+case 23:
+#line 99 "uparse.y"
+{ list_disk_history(); }
+    break;
+case 24:
+#line 100 "uparse.y"
+{ list_directory(); }
+    break;
+case 25:
+#line 101 "uparse.y"
+{ display_extract_list(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 26:
+#line 102 "uparse.y"
+{ display_extract_list(NULL); }
+    break;
+case 27:
+#line 103 "uparse.y"
+{ show_directory(); }
+    break;
+case 28:
+#line 104 "uparse.y"
+{ clear_extract_list(); }
+    break;
+case 29:
+#line 105 "uparse.y"
+{ show_mode (); }
+    break;
+case 30:
+#line 109 "uparse.y"
+{ quit(); }
+    break;
+case 32:
+#line 117 "uparse.y"
+{ add_glob(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 33:
+#line 118 "uparse.y"
+{ add_glob(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 35:
+#line 126 "uparse.y"
+{ add_regex(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 36:
+#line 127 "uparse.y"
+{ add_regex(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 38:
+#line 135 "uparse.y"
+{ delete_glob(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 39:
+#line 136 "uparse.y"
+{ delete_glob(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 41:
+#line 144 "uparse.y"
+{ delete_regex(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 42:
+#line 145 "uparse.y"
+{ delete_regex(yyvsp[0].strval); amfree(yyvsp[0].strval); }
+    break;
+case 43:
+#line 149 "uparse.y"
+{ char buf[STR_SIZE]; puts(getcwd(buf, sizeof(buf))); }
+    break;
+case 44:
+#line 150 "uparse.y"
+{
+               if (chdir(yyvsp[0].strval) == -1) {
+                       perror(yyvsp[0].strval);
+               }
+               amfree(yyvsp[0].strval);
+       }
+    break;
+case 45:
+#line 159 "uparse.y"
+{ help_list(); }
+    break;
+case 46:
+#line 163 "uparse.y"
+{ extract_files(); }
+    break;
+}
+
+#line 705 "/usr/share/bison/bison.simple"
+
+\f
+  yyvsp -= yylen;
+  yyssp -= yylen;
+#if YYLSP_NEEDED
+  yylsp -= yylen;
+#endif
+
+#if YYDEBUG
+  if (yydebug)
+    {
+      short *yyssp1 = yyss - 1;
+      YYFPRINTF (stderr, "state stack now");
+      while (yyssp1 != yyssp)
+       YYFPRINTF (stderr, " %d", *++yyssp1);
+      YYFPRINTF (stderr, "\n");
+    }
+#endif
+
+  *++yyvsp = yyval;
+#if YYLSP_NEEDED
+  *++yylsp = yyloc;
+#endif
+
+  /* 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 - YYNTBASE] + *yyssp;
+  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTBASE];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+
+#ifdef YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (yyn > YYFLAG && yyn < YYLAST)
+       {
+         YYSIZE_T yysize = 0;
+         char *yymsg;
+         int yyx, yycount;
+
+         yycount = 0;
+         /* Start YYX at -YYN if negative to avoid negative indexes in
+            YYCHECK.  */
+         for (yyx = yyn < 0 ? -yyn : 0;
+              yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+           if (yycheck[yyx + yyn] == yyx)
+             yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+         yysize += yystrlen ("parse error, unexpected ") + 1;
+         yysize += yystrlen (yytname[YYTRANSLATE (yychar)]);
+         yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg != 0)
+           {
+             char *yyp = yystpcpy (yymsg, "parse error, unexpected ");
+             yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]);
+
+             if (yycount < 5)
+               {
+                 yycount = 0;
+                 for (yyx = yyn < 0 ? -yyn : 0;
+                      yyx < (int) (sizeof (yytname) / sizeof (char *));
+                      yyx++)
+                   if (yycheck[yyx + yyn] == yyx)
+                     {
+                       const char *yyq = ! yycount ? ", expecting " : " or ";
+                       yyp = yystpcpy (yyp, yyq);
+                       yyp = yystpcpy (yyp, yytname[yyx]);
+                       yycount++;
+                     }
+               }
+             yyerror (yymsg);
+             YYSTACK_FREE (yymsg);
+           }
+         else
+           yyerror ("parse error; also virtual memory exhausted");
+       }
+      else
+#endif /* defined (YYERROR_VERBOSE) */
+       yyerror ("parse error");
+    }
+  goto yyerrlab1;
+
+
+/*--------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action |
+`--------------------------------------------------*/
+yyerrlab1:
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+        error, discard it.  */
+
+      /* return failure if at end of input */
+      if (yychar == YYEOF)
+       YYABORT;
+      YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
+                 yychar, yytname[yychar1]));
+      yychar = YYEMPTY;
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+
+  yyerrstatus = 3;             /* Each real token shifted decrements this */
+
+  goto yyerrhandle;
+
+
+/*-------------------------------------------------------------------.
+| yyerrdefault -- current state does not do anything special for the |
+| error token.                                                       |
+`-------------------------------------------------------------------*/
+yyerrdefault:
+#if 0
+  /* This is wrong; only states that explicitly want error tokens
+     should shift them.  */
+
+  /* If its default is to accept any token, ok.  Otherwise pop it.  */
+  yyn = yydefact[yystate];
+  if (yyn)
+    goto yydefault;
+#endif
+
+
+/*---------------------------------------------------------------.
+| yyerrpop -- pop the current state because it cannot handle the |
+| error token                                                    |
+`---------------------------------------------------------------*/
+yyerrpop:
+  if (yyssp == yyss)
+    YYABORT;
+  yyvsp--;
+  yystate = *--yyssp;
+#if YYLSP_NEEDED
+  yylsp--;
+#endif
+
+#if YYDEBUG
+  if (yydebug)
+    {
+      short *yyssp1 = yyss - 1;
+      YYFPRINTF (stderr, "Error: state stack now");
+      while (yyssp1 != yyssp)
+       YYFPRINTF (stderr, " %d", *++yyssp1);
+      YYFPRINTF (stderr, "\n");
+    }
+#endif
+
+/*--------------.
+| yyerrhandle.  |
+`--------------*/
+yyerrhandle:
+  yyn = yypact[yystate];
+  if (yyn == YYFLAG)
+    goto yyerrdefault;
+
+  yyn += YYTERROR;
+  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
+    goto yyerrdefault;
+
+  yyn = yytable[yyn];
+  if (yyn < 0)
+    {
+      if (yyn == YYFLAG)
+       goto yyerrpop;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+  else if (yyn == 0)
+    goto yyerrpop;
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  YYDPRINTF ((stderr, "Shifting error token, "));
+
+  *++yyvsp = yylval;
+#if YYLSP_NEEDED
+  *++yylsp = yylloc;
+#endif
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+/*---------------------------------------------.
+| yyoverflowab -- parser overflow comes here.  |
+`---------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
+
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+#line 167 "uparse.y"
+
+
+void yyerror(s)
+char *s;
+{
+  printf("Invalid command - %s\n", s);
+}
+
+
diff --git a/recover-src/uparse.h b/recover-src/uparse.h
new file mode 100644 (file)
index 0000000..3c60816
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef BISON_UPARSE_H
+# define BISON_UPARSE_H
+
+#ifndef YYSTYPE
+typedef union {
+  int intval;
+  double floatval;
+  char *strval;
+  int subtok;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define       LISTDISK        257
+# define       SETHOST 258
+# define       SETDISK 259
+# define       SETDATE 260
+# define       SETTAPE 261
+# define       SETMODE 262
+# define       CD      263
+# define       CDX     264
+# define       QUIT    265
+# define       DHIST   266
+# define       LS      267
+# define       ADD     268
+# define       ADDX    269
+# define       EXTRACT 270
+# define       LIST    271
+# define       DELETE  272
+# define       DELETEX 273
+# define       PWD     274
+# define       CLEAR   275
+# define       HELP    276
+# define       LCD     277
+# define       LPWD    278
+# define       MODE    279
+# define       SMB     280
+# define       TAR     281
+# define       PATH    282
+# define       DATE    283
+
+
+extern YYSTYPE yylval;
+
+#endif /* not BISON_UPARSE_H */
diff --git a/recover-src/uparse.y b/recover-src/uparse.y
new file mode 100644 (file)
index 0000000..3624cce
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * 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.5.4.2.4.1.2.3 2003/01/01 23:28:52 martinea Exp $
+ *
+ * parser for amrecover interactive language
+ */
+%{
+#include "amanda.h"
+#include "amrecover.h"
+
+void yyerror P((char *s));
+extern int yylex P((void));
+%}
+
+/* DECLARATIONS */
+%union {
+  int intval;
+  double floatval;
+  char *strval;
+  int subtok;
+}
+
+       /* literal keyword tokens */
+
+%token 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
+  ;
+
+set_command:
+       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(s)
+char *s;
+{
+  printf("Invalid command - %s\n", s);
+}
+
+
diff --git a/recover-src/uscan.c b/recover-src/uscan.c
new file mode 100644 (file)
index 0000000..a30a0b9
--- /dev/null
@@ -0,0 +1,1895 @@
+/* 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 )
+
+/* 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 ));
+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 38
+#define YY_END_OF_BUFFER 39
+static yyconst short int yy_accept[121] =
+    {   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
+    } ;
+
+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,
+        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
+    } ;
+
+static yyconst int yy_meta[29] =
+    {   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
+    } ;
+
+static yyconst short int yy_base[124] =
+    {   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
+    } ;
+
+static yyconst short int yy_def[124] =
+    {   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
+    } ;
+
+static yyconst short int yy_nxt[172] =
+    {   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
+    } ;
+
+static yyconst short int yy_chk[172] =
+    {   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
+    } ;
+
+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.14.2.3.4.1.2.3 2004/02/11 13:03:52 martinea Exp $
+ *
+ * lexer for amrecover interactive language
+ */
+#line 32 "uscan.l"
+#include "amanda.h"
+#undef ECHO
+#include "uparse.h"
+
+#define YY_NO_UNPUT
+
+#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD")    /* includes null */
+
+extern void yyerror P((char *s));
+extern int  yyparse P((void));
+static int  ll_parse_date P((int type, char *text));
+#define quotedstring 1
+
+#line 48 "uscan.l"
+static char *string_buf = NULL;
+#line 485 "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 51 "uscan.l"
+
+
+
+    /* literal keyword tokens */
+
+
+#line 643 "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 >= 121 )
+                                       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 );
+
+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 57 "uscan.l"
+{ return LISTDISK; }
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 58 "uscan.l"
+{ return SETHOST; }
+       YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 59 "uscan.l"
+{ return SETDISK; }
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 60 "uscan.l"
+{ return SETDATE; }
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 61 "uscan.l"
+{ return SETMODE; }
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 62 "uscan.l"
+{ return SETTAPE; }
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 63 "uscan.l"
+{ return CD; }
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 64 "uscan.l"
+{ return CDX; }
+       YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 65 "uscan.l"
+{ return QUIT; }
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 66 "uscan.l"
+{ return QUIT; }
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 67 "uscan.l"
+{ return DHIST; }
+       YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 68 "uscan.l"
+{ return LS; }
+       YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 69 "uscan.l"
+{ return ADD; }
+       YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 70 "uscan.l"
+{ return ADDX; }
+       YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 71 "uscan.l"
+{ return LIST; }
+       YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 72 "uscan.l"
+{ return DELETE; }
+       YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 73 "uscan.l"
+{ return DELETEX; }
+       YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 74 "uscan.l"
+{ return PWD; }
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 75 "uscan.l"
+{ return CLEAR; }
+       YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 76 "uscan.l"
+{ return HELP; }
+       YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 77 "uscan.l"
+{ return HELP; }
+       YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 78 "uscan.l"
+{ return LCD; }
+       YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 79 "uscan.l"
+{ return LPWD; }
+       YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 80 "uscan.l"
+{ return EXTRACT; }
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 81 "uscan.l"
+{ return SMB; }
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 82 "uscan.l"
+{ return TAR; }
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 83 "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); }
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 91 "uscan.l"
+{ return ll_parse_date(3, yytext); }
+       YY_BREAK
+
+    /* file names */
+
+case 31:
+YY_RULE_SETUP
+#line 97 "uscan.l"
+{
+  yylval.strval = stralloc(yytext); return PATH;
+}
+       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); }
+       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;
+}
+       YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 118 "uscan.l"
+{
+  /* escaped quote */
+  strappend(string_buf, "\\\"");
+}
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 123 "uscan.l"
+{
+  /* error - unterminated string constant */
+  yyerror("unterminated string");
+  amfree(string_buf);
+}
+       YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 129 "uscan.l"
+{ strappend(string_buf, yytext); }
+       YY_BREAK
+
+    /* whitespace */
+
+case 37:
+YY_RULE_SETUP
+#line 135 "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 38:
+YY_RULE_SETUP
+#line 148 "uscan.l"
+ECHO;
+       YY_BREAK
+#line 955 "uscan.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(quotedstring):
+       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 >= 121 )
+                               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 >= 121 )
+                       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);
+
+       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 148 "uscan.l"
+
+
+int process_line(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(type, text)
+int type;
+char *text;
+{
+    time_t now;
+    struct tm *t;
+    int y, m, d;
+    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;
+       }
+    }
+    ret = PATH;                                /* cause a parse error */
+    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 {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       ap_snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
+       ret = DATE;
+    }
+    return ret;
+}
+
+int yywrap() {
+  return 1;
+}
diff --git a/recover-src/uscan.l b/recover-src/uscan.l
new file mode 100644 (file)
index 0000000..2a53cfa
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * 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.14.2.3.4.1.2.3 2004/02/11 13:03:52 martinea Exp $
+ *
+ * lexer for amrecover interactive language
+ */
+%{
+#include "amanda.h"
+#undef ECHO
+#include "uparse.h"
+
+#define YY_NO_UNPUT
+
+#define        DATE_ALLOC_SIZE         sizeof("YYYY-MM-DD")    /* includes null */
+
+extern void yyerror P((char *s));
+extern int  yyparse P((void));
+static int  ll_parse_date P((int type, char *text));
+%}
+
+%x quotedstring
+
+%{
+static char *string_buf = NULL;
+%}
+
+%%
+
+%{
+    /* literal keyword tokens */
+%}
+
+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); }
+
+%{
+    /* file names */
+%}
+
+[^ \t\r"]+             {
+  yylval.strval = stralloc(yytext); return PATH;
+}
+
+%{
+    /* quoted file names */
+%}
+
+\"               { if(string_buf != NULL) {printf("ERROR:string_buf != NULL: %s\n",string_buf);}; BEGIN(quotedstring); }
+
+<quotedstring>\"        { /* saw closing quote - all done */
+  BEGIN(INITIAL);
+  if(string_buf) {
+    yylval.strval = string_buf;
+    string_buf = NULL;
+  } else {
+    yylval.strval = "";
+  }
+  return PATH;
+}
+
+<quotedstring>\\\" {
+  /* escaped quote */
+  strappend(string_buf, "\\\"");
+}
+
+<quotedstring>\n        {
+  /* error - unterminated string constant */
+  yyerror("unterminated string");
+  amfree(string_buf);
+}
+
+<quotedstring>[^\\\n\"]+        { strappend(string_buf, yytext); }
+
+%{
+    /* whitespace */
+%}
+
+[ \t\r]+       ;     /* whitespace */
+
+%{
+    /* anything else */
+    /* everything should have been handled by now, so this rule is disabled */
+%}
+
+%{
+#if 0
+.      { yyerror("invalid character"); }
+#endif
+%}
+
+%%
+
+int process_line(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(type, text)
+int type;
+char *text;
+{
+    time_t now;
+    struct tm *t;
+    int y, m, d;
+    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;
+       }
+    }
+    ret = PATH;                                /* cause a parse error */
+    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 {
+       yylval.strval = alloc(DATE_ALLOC_SIZE);
+       ap_snprintf(yylval.strval, DATE_ALLOC_SIZE, "%04d-%02d-%02d", y, m, d);
+       ret = DATE;
+    }
+    return ret;
+}
+
+int yywrap() {
+  return 1;
+}
diff --git a/regex-src/COPYRIGHT b/regex-src/COPYRIGHT
new file mode 100644 (file)
index 0000000..30c1f7a
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright 1992, 1993, 1994, 1997 Henry Spencer.  All rights reserved.
+This software is not subject to any license of the American Telephone
+and Telegraph Company or of the Regents of the University of California.
+
+Permission is granted to anyone to use this software for any purpose on
+any computer system, and to alter it and redistribute it, subject
+to the following restrictions:
+
+1. The author is not responsible for the consequences of use of this
+   software, no matter how awful, even if they arise from flaws in it.
+
+2. The origin of this software must not be misrepresented, either by
+   explicit claim or by omission.  Since few users ever read sources,
+   credits must appear in the documentation.
+
+3. Altered versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.  Since few users
+   ever read sources, credits must appear in the documentation.
+
+4. This notice may not be removed or altered.
diff --git a/regex-src/Makefile b/regex-src/Makefile
new file mode 100644 (file)
index 0000000..3882b37
--- /dev/null
@@ -0,0 +1,130 @@
+# You probably want to take -DREDEBUG out of CFLAGS, and put something like
+# -O in, *after* testing (-DREDEBUG strengthens testing by enabling a lot of
+# internal assertion checking and some debugging facilities).
+# Put -Dconst= in for a pre-ANSI compiler.
+# Do not take -DPOSIX_MISTAKE out.
+# REGCFLAGS isn't important to you (it's for my use in some special contexts).
+CFLAGS=-I. -DPOSIX_MISTAKE -DREDEBUG $(REGCFLAGS)
+
+# If you have a pre-ANSI compiler, put -o into MKHFLAGS.  If you want
+# the Berkeley __P macro, put -b in.
+MKHFLAGS=
+
+# Flags for linking but not compiling, if any.
+LDFLAGS=
+
+# Extra libraries for linking, if any.
+LIBS=
+
+# Internal stuff, should not need changing.
+OBJPRODN=regcomp.o regexec.o regerror.o regfree.o
+OBJS=$(OBJPRODN) split.o debug.o main.o
+H=cclass.h cname.h regex2.h utils.h
+REGSRC=regcomp.c regerror.c regexec.c regfree.c
+ALLSRC=$(REGSRC) engine.c debug.c main.c split.c
+
+# Stuff that matters only if you're trying to lint the package.
+LINTFLAGS=-I. -Dstatic= -Dconst= -DREDEBUG
+LINTC=regcomp.c regexec.c regerror.c regfree.c debug.c main.c
+JUNKLINT=possible pointer alignment|null effect
+
+# arrangements to build forward-reference header files
+.SUFFIXES:     .ih .h
+.c.ih:
+       sh ./mkh $(MKHFLAGS) -p $< >$@
+
+default:       r
+
+lib:   purge $(OBJPRODN)
+       rm -f libregex.a
+       ar crv libregex.a $(OBJPRODN)
+
+purge:
+       rm -f *.o
+
+# stuff to build regex.h
+REGEXH=regex.h
+REGEXHSRC=regex2.h $(REGSRC)
+$(REGEXH):     $(REGEXHSRC) mkh
+       sh ./mkh $(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
+
+# dependencies
+$(OBJPRODN) debug.o:   utils.h regex.h regex2.h
+regcomp.o:     cclass.h cname.h regcomp.ih
+regexec.o:     engine.c engine.ih
+regerror.o:    regerror.ih
+debug.o:       debug.ih
+main.o:        main.ih
+
+# tester
+re:    $(OBJS)
+       $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
+
+# regression test
+r:     re tests
+       ./re <tests
+       ./re -el <tests
+       ./re -er <tests
+
+# 57 variants, and other stuff, for development use -- not useful to you
+ra:    ./re tests
+       -./re <tests
+       -./re -el <tests
+       -./re -er <tests
+
+rx:    ./re tests
+       ./re -x <tests
+       ./re -x -el <tests
+       ./re -x -er <tests
+
+t:     ./re tests
+       -time ./re <tests
+       -time ./re -cs <tests
+       -time ./re -el <tests
+       -time ./re -cs -el <tests
+
+l:     $(LINTC)
+       lint $(LINTFLAGS) -h $(LINTC) 2>&1 | egrep -v '$(JUNKLINT)' | tee lint
+
+fullprint:
+       ti README WHATSNEW notes todo | list
+       ti *.h | list
+       list *.c
+       list regex.3 regex.7
+
+print:
+       ti README WHATSNEW notes todo | list
+       ti *.h | list
+       list reg*.c engine.c
+
+
+mf.tmp:        Makefile
+       sed '/^REGEXH=/s/=.*/=regex.h/' Makefile | sed '/#DEL$$/d' >$@
+
+DTRH=cclass.h cname.h regex2.h utils.h
+PRE=COPYRIGHT README WHATSNEW
+POST=mkh regex.3 regex.7 tests $(DTRH) $(ALLSRC) fake/*.[ch]
+FILES=$(PRE) Makefile $(POST)
+DTR=$(PRE) Makefile=mf.tmp $(POST)
+dtr:   $(FILES) mf.tmp
+       makedtr $(DTR) >$@
+       rm mf.tmp
+
+cio:   $(FILES)
+       cio $(FILES)
+
+rdf:   $(FILES)
+       rcsdiff -c $(FILES) 2>&1 | p
+
+# various forms of cleanup
+tidy:
+       rm -f junk* core core.* *.core dtr *.tmp lint
+
+clean: tidy
+       rm -f *.o *.s *.ih re libregex.a
+
+# don't do this one unless you know what you're doing
+spotless:      clean
+       rm -f mkh regex.h
diff --git a/regex-src/README b/regex-src/README
new file mode 100644 (file)
index 0000000..166b181
--- /dev/null
@@ -0,0 +1,32 @@
+alpha3.6 release.
+Tue Sep 30 13:46:32 EDT 1997
+henry@zoo.toronto.edu
+
+See WHATSNEW for change listing.
+
+installation notes:
+--------
+Read the comments at the beginning of Makefile before running.
+
+Utils.h contains some things that just might have to be modified on
+some systems, as well as a nested include (ugh) of <assert.h>.
+
+The "fake" directory contains quick-and-dirty fakes for some header
+files and routines that old systems may not have.  Note also that
+-DUSEBCOPY will make utils.h substitute bcopy() for memmove().
+
+After that, "make r" will build regcomp.o, regexec.o, regfree.o,
+and regerror.o (the actual routines), bundle them together into a test
+program, and run regression tests on them.  No output is good output.
+
+"make lib" builds just the .o files for the actual routines (when
+you're happy with testing and have adjusted CFLAGS for production),
+and puts them together into libregex.a.  You can pick up either the
+library or *.o ("make lib" makes sure there are no other .o files left
+around to confuse things).
+
+Main.c, debug.c, split.c are used for regression testing but are not part
+of the RE routines themselves.
+
+Regex.h goes in /usr/include.  All other .h files are internal only.
+--------
diff --git a/regex-src/WHATSNEW b/regex-src/WHATSNEW
new file mode 100644 (file)
index 0000000..230ca86
--- /dev/null
@@ -0,0 +1,101 @@
+New in alpha3.6:  A couple more portability glitches fixed.
+
+New in alpha3.5:  Active development of this code has been stopped --
+I'm working on a complete reimplementation -- but folks have found some
+minor portability glitches and the like, hence this release to fix them.
+One penalty:  slightly reduced compatibility with old compilers, because
+the ANSI C `unsigned long' type and `ul' constant suffix are used in a
+few places (I could avoid this but it would be considerably more work).
+
+New in alpha3.4:  The complex bug alluded to below has been fixed (in a
+slightly kludgey temporary way that may hurt efficiency a bit; this is
+another "get it out the door for 4.4" release).  The tests at the end of
+the tests file have accordingly been uncommented.  The primary sign of
+the bug was that something like a?b matching ab matched b rather than ab.
+(The bug was essentially specific to this exact situation, else it would
+have shown up earlier.)
+
+New in alpha3.3:  The definition of word boundaries has been altered
+slightly, to more closely match the usual programming notion that "_"
+is an alphabetic.  Stuff used for pre-ANSI systems is now in a subdir,
+and the makefile no longer alludes to it in mysterious ways.  The
+makefile has generally been cleaned up some.  Fixes have been made
+(again!) so that the regression test will run without -DREDEBUG, at
+the cost of weaker checking.  A workaround for a bug in some folks'
+<assert.h> has been added.  And some more things have been added to
+tests, including a couple right at the end which are commented out
+because the code currently flunks them (complex bug; fix coming).
+Plus the usual minor cleanup.
+
+New in alpha3.2:  Assorted bits of cleanup and portability improvement
+(the development base is now a BSDI system using GCC instead of an ancient
+Sun system, and the newer compiler exposed some glitches).  Fix for a
+serious bug that affected REs using many [] (including REG_ICASE REs
+because of the way they are implemented), *sometimes*, depending on
+memory-allocation patterns.  The header-file prototypes no longer name
+the parameters, avoiding possible name conflicts.  The possibility that
+some clot has defined CHAR_MIN as (say) `-128' instead of `(-128)' is
+now handled gracefully.  "uchar" is no longer used as an internal type
+name (too many people have the same idea).  Still the same old lousy
+performance, alas.
+
+New in alpha3.1:  Basically nothing, this release is just a bookkeeping
+convenience.  Stay tuned.
+
+New in alpha3.0:  Performance is no better, alas, but some fixes have been
+made and some functionality has been added.  (This is basically the "get
+it out the door in time for 4.4" release.)  One bug fix:  regfree() didn't
+free the main internal structure (how embarrassing).  It is now possible
+to put NULs in either the RE or the target string, using (resp.) a new
+REG_PEND flag and the old REG_STARTEND flag.  The REG_NOSPEC flag to
+regcomp() makes all characters ordinary, so you can match a literal
+string easily (this will become more useful when performance improves!).
+There are now primitives to match beginnings and ends of words, although
+the syntax is disgusting and so is the implementation.  The REG_ATOI
+debugging interface has changed a bit.  And there has been considerable
+internal cleanup of various kinds.
+
+New in alpha2.3:  Split change list out of README, and moved flags notes
+into Makefile.  Macro-ized the name of regex(7) in regex(3), since it has
+to change for 4.4BSD.  Cleanup work in engine.c, and some new regression
+tests to catch tricky cases thereof.
+
+New in alpha2.2:  Out-of-date manpages updated.  Regerror() acquires two
+small extensions -- REG_ITOA and REG_ATOI -- which avoid debugging kludges
+in my own test program and might be useful to others for similar purposes.
+The regression test will now compile (and run) without REDEBUG.  The
+BRE \$ bug is fixed.  Most uses of "uchar" are gone; it's all chars now.
+Char/uchar parameters are now written int/unsigned, to avoid possible
+portability problems with unpromoted parameters.  Some unsigned casts have
+been introduced to minimize portability problems with shifting into sign
+bits.
+
+New in alpha2.1:  Lots of little stuff, cleanup and fixes.  The one big
+thing is that regex.h is now generated, using mkh, rather than being
+supplied in the distribution; due to circularities in dependencies,
+you have to build regex.h explicitly by "make h".  The two known bugs
+have been fixed (and the regression test now checks for them), as has a
+problem with assertions not being suppressed in the absence of REDEBUG.
+No performance work yet.
+
+New in alpha2:  Backslash-anything is an ordinary character, not an
+error (except, of course, for the handful of backslashed metacharacters
+in BREs), which should reduce script breakage.  The regression test
+checks *where* null strings are supposed to match, and has generally
+been tightened up somewhat.  Small bug fixes in parameter passing (not
+harmful, but technically errors) and some other areas.  Debugging
+invoked by defining REDEBUG rather than not defining NDEBUG.
+
+New in alpha+3:  full prototyping for internal routines, using a little
+helper program, mkh, which extracts prototypes given in stylized comments.
+More minor cleanup.  Buglet fix:  it's CHAR_BIT, not CHAR_BITS.  Simple
+pre-screening of input when a literal string is known to be part of the
+RE; this does wonders for performance.
+
+New in alpha+2:  minor bits of cleanup.  Notably, the number "32" for the
+word width isn't hardwired into regexec.c any more, the public header
+file prototypes the functions if __STDC__ is defined, and some small typos
+in the manpages have been fixed.
+
+New in alpha+1:  improvements to the manual pages, and an important
+extension, the REG_STARTEND option to regexec().
diff --git a/regex-src/cclass.h b/regex-src/cclass.h
new file mode 100644 (file)
index 0000000..0c29302
--- /dev/null
@@ -0,0 +1,31 @@
+/* character-class table */
+static struct cclass {
+       char *name;
+       char *chars;
+       char *multis;
+} cclasses[] = {
+       "alnum",        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789",                           "",
+       "alpha",        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
+                                       "",
+       "blank",        " \t",          "",
+       "cntrl",        "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\
+\25\26\27\30\31\32\33\34\35\36\37\177",        "",
+       "digit",        "0123456789",   "",
+       "graph",        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+                                       "",
+       "lower",        "abcdefghijklmnopqrstuvwxyz",
+                                       "",
+       "print",        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\
+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ",
+                                       "",
+       "punct",        "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
+                                       "",
+       "space",        "\t\n\v\f\r ",  "",
+       "upper",        "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+                                       "",
+       "xdigit",       "0123456789ABCDEFabcdef",
+                                       "",
+       NULL,           0,              ""
+};
diff --git a/regex-src/cname.h b/regex-src/cname.h
new file mode 100644 (file)
index 0000000..02e86e9
--- /dev/null
@@ -0,0 +1,102 @@
+/* character-name table */
+static struct cname {
+       char *name;
+       char code;
+} cnames[] = {
+       "NUL",  '\0',
+       "SOH",  '\001',
+       "STX",  '\002',
+       "ETX",  '\003',
+       "EOT",  '\004',
+       "ENQ",  '\005',
+       "ACK",  '\006',
+       "BEL",  '\007',
+       "alert",        '\007',
+       "BS",           '\010',
+       "backspace",    '\b',
+       "HT",           '\011',
+       "tab",          '\t',
+       "LF",           '\012',
+       "newline",      '\n',
+       "VT",           '\013',
+       "vertical-tab", '\v',
+       "FF",           '\014',
+       "form-feed",    '\f',
+       "CR",           '\015',
+       "carriage-return",      '\r',
+       "SO",   '\016',
+       "SI",   '\017',
+       "DLE",  '\020',
+       "DC1",  '\021',
+       "DC2",  '\022',
+       "DC3",  '\023',
+       "DC4",  '\024',
+       "NAK",  '\025',
+       "SYN",  '\026',
+       "ETB",  '\027',
+       "CAN",  '\030',
+       "EM",   '\031',
+       "SUB",  '\032',
+       "ESC",  '\033',
+       "IS4",  '\034',
+       "FS",   '\034',
+       "IS3",  '\035',
+       "GS",   '\035',
+       "IS2",  '\036',
+       "RS",   '\036',
+       "IS1",  '\037',
+       "US",   '\037',
+       "space",                ' ',
+       "exclamation-mark",     '!',
+       "quotation-mark",       '"',
+       "number-sign",          '#',
+       "dollar-sign",          '$',
+       "percent-sign",         '%',
+       "ampersand",            '&',
+       "apostrophe",           '\'',
+       "left-parenthesis",     '(',
+       "right-parenthesis",    ')',
+       "asterisk",     '*',
+       "plus-sign",    '+',
+       "comma",        ',',
+       "hyphen",       '-',
+       "hyphen-minus", '-',
+       "period",       '.',
+       "full-stop",    '.',
+       "slash",        '/',
+       "solidus",      '/',
+       "zero",         '0',
+       "one",          '1',
+       "two",          '2',
+       "three",        '3',
+       "four",         '4',
+       "five",         '5',
+       "six",          '6',
+       "seven",        '7',
+       "eight",        '8',
+       "nine",         '9',
+       "colon",        ':',
+       "semicolon",    ';',
+       "less-than-sign",       '<',
+       "equals-sign",          '=',
+       "greater-than-sign",    '>',
+       "question-mark",        '?',
+       "commercial-at",        '@',
+       "left-square-bracket",  '[',
+       "backslash",            '\\',
+       "reverse-solidus",      '\\',
+       "right-square-bracket", ']',
+       "circumflex",           '^',
+       "circumflex-accent",    '^',
+       "underscore",           '_',
+       "low-line",             '_',
+       "grave-accent",         '`',
+       "left-brace",           '{',
+       "left-curly-bracket",   '{',
+       "vertical-line",        '|',
+       "right-brace",          '}',
+       "right-curly-bracket",  '}',
+       "tilde",                '~',
+       "DEL",  '\177',
+       NULL,   0,
+};
diff --git a/regex-src/debug.c b/regex-src/debug.c
new file mode 100644 (file)
index 0000000..d473682
--- /dev/null
@@ -0,0 +1,242 @@
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <regex.h>
+
+#include "utils.h"
+#include "regex2.h"
+#include "debug.ih"
+
+/*
+ - regprint - print a regexp for debugging
+ == void regprint(regex_t *r, FILE *d);
+ */
+void
+regprint(r, d)
+regex_t *r;
+FILE *d;
+{
+       register struct re_guts *g = r->re_g;
+       register int i;
+       register int c;
+       register int last;
+       int nincat[NC];
+
+       fprintf(d, "%ld states, %d categories", (long)g->nstates,
+                                                       g->ncategories);
+       fprintf(d, ", first %ld last %ld", (long)g->firststate,
+                                               (long)g->laststate);
+       if (g->iflags&USEBOL)
+               fprintf(d, ", USEBOL");
+       if (g->iflags&USEEOL)
+               fprintf(d, ", USEEOL");
+       if (g->iflags&BAD)
+               fprintf(d, ", BAD");
+       if (g->nsub > 0)
+               fprintf(d, ", nsub=%ld", (long)g->nsub);
+       if (g->must != NULL)
+               fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
+                                                               g->must);
+       if (g->backrefs)
+               fprintf(d, ", backrefs");
+       if (g->nplus > 0)
+               fprintf(d, ", nplus %ld", (long)g->nplus);
+       fprintf(d, "\n");
+       s_print(g, d);
+       for (i = 0; i < g->ncategories; i++) {
+               nincat[i] = 0;
+               for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+                       if (g->categories[c] == i)
+                               nincat[i]++;
+       }
+       fprintf(d, "cc0#%d", nincat[0]);
+       for (i = 1; i < g->ncategories; i++)
+               if (nincat[i] == 1) {
+                       for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+                               if (g->categories[c] == i)
+                                       break;
+                       fprintf(d, ", %d=%s", i, regchar(c));
+               }
+       fprintf(d, "\n");
+       for (i = 1; i < g->ncategories; i++)
+               if (nincat[i] != 1) {
+                       fprintf(d, "cc%d\t", i);
+                       last = -1;
+                       for (c = CHAR_MIN; c <= CHAR_MAX+1; c++)        /* +1 does flush */
+                               if (c <= CHAR_MAX && g->categories[c] == i) {
+                                       if (last < 0) {
+                                               fprintf(d, "%s", regchar(c));
+                                               last = c;
+                                       }
+                               } else {
+                                       if (last >= 0) {
+                                               if (last != c-1)
+                                                       fprintf(d, "-%s",
+                                                               regchar(c-1));
+                                               last = -1;
+                                       }
+                               }
+                       fprintf(d, "\n");
+               }
+}
+
+/*
+ - s_print - print the strip for debugging
+ == static void s_print(register struct re_guts *g, FILE *d);
+ */
+static void
+s_print(g, d)
+register struct re_guts *g;
+FILE *d;
+{
+       register sop *s;
+       register cset *cs;
+       register int i;
+       register int done = 0;
+       register sop opnd;
+       register int col = 0;
+       register int last;
+       register sopno offset = 2;
+#      define  GAP()   {       if (offset % 5 == 0) { \
+                                       if (col > 40) { \
+                                               fprintf(d, "\n\t"); \
+                                               col = 0; \
+                                       } else { \
+                                               fprintf(d, " "); \
+                                               col++; \
+                                       } \
+                               } else \
+                                       col++; \
+                               offset++; \
+                       }
+
+       if (OP(g->strip[0]) != OEND)
+               fprintf(d, "missing initial OEND!\n");
+       for (s = &g->strip[1]; !done; s++) {
+               opnd = OPND(*s);
+               switch (OP(*s)) {
+               case OEND:
+                       fprintf(d, "\n");
+                       done = 1;
+                       break;
+               case OCHAR:
+                       if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
+                               fprintf(d, "\\%c", (char)opnd);
+                       else
+                               fprintf(d, "%s", regchar((char)opnd));
+                       break;
+               case OBOL:
+                       fprintf(d, "^");
+                       break;
+               case OEOL:
+                       fprintf(d, "$");
+                       break;
+               case OBOW:
+                       fprintf(d, "\\{");
+                       break;
+               case OEOW:
+                       fprintf(d, "\\}");
+                       break;
+               case OANY:
+                       fprintf(d, ".");
+                       break;
+               case OANYOF:
+                       fprintf(d, "[(%ld)", (long)opnd);
+                       cs = &g->sets[opnd];
+                       last = -1;
+                       for (i = 0; i < g->csetsize+1; i++)     /* +1 flushes */
+                               if (CHIN(cs, i) && i < g->csetsize) {
+                                       if (last < 0) {
+                                               fprintf(d, "%s", regchar(i));
+                                               last = i;
+                                       }
+                               } else {
+                                       if (last >= 0) {
+                                               if (last != i-1)
+                                                       fprintf(d, "-%s",
+                                                               regchar(i-1));
+                                               last = -1;
+                                       }
+                               }
+                       fprintf(d, "]");
+                       break;
+               case OBACK_:
+                       fprintf(d, "(\\<%ld>", (long)opnd);
+                       break;
+               case O_BACK:
+                       fprintf(d, "<%ld>\\)", (long)opnd);
+                       break;
+               case OPLUS_:
+                       fprintf(d, "(+");
+                       if (OP(*(s+opnd)) != O_PLUS)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       break;
+               case O_PLUS:
+                       if (OP(*(s-opnd)) != OPLUS_)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       fprintf(d, "+)");
+                       break;
+               case OQUEST_:
+                       fprintf(d, "(?");
+                       if (OP(*(s+opnd)) != O_QUEST)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       break;
+               case O_QUEST:
+                       if (OP(*(s-opnd)) != OQUEST_)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       fprintf(d, "?)");
+                       break;
+               case OLPAREN:
+                       fprintf(d, "((<%ld>", (long)opnd);
+                       break;
+               case ORPAREN:
+                       fprintf(d, "<%ld>))", (long)opnd);
+                       break;
+               case OCH_:
+                       fprintf(d, "<");
+                       if (OP(*(s+opnd)) != OOR2)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       break;
+               case OOR1:
+                       if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       fprintf(d, "|");
+                       break;
+               case OOR2:
+                       fprintf(d, "|");
+                       if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       break;
+               case O_CH:
+                       if (OP(*(s-opnd)) != OOR1)
+                               fprintf(d, "<%ld>", (long)opnd);
+                       fprintf(d, ">");
+                       break;
+               default:
+                       fprintf(d, "!%d(%d)!", OP(*s), opnd);
+                       break;
+               }
+               if (!done)
+                       GAP();
+       }
+}
+
+/*
+ - regchar - make a character printable
+ == static char *regchar(int ch);
+ */
+static char *                  /* -> representation */
+regchar(ch)
+int ch;
+{
+       static char buf[10];
+
+       if (isprint(ch) || ch == ' ')
+               ap_snprintf(buf, sizeof(buf), "%c", ch);
+       else
+               ap_snprintf(buf, sizeof(buf), "\\%o", ch);
+       return(buf);
+}
diff --git a/regex-src/engine.c b/regex-src/engine.c
new file mode 100644 (file)
index 0000000..1739cd5
--- /dev/null
@@ -0,0 +1,1019 @@
+/*
+ * The matching engine and friends.  This file is #included by regexec.c
+ * after suitable #defines of a variety of macros used herein, so that
+ * different state representations can be used without duplicating masses
+ * of code.
+ */
+
+#ifdef SNAMES
+#define        matcher smatcher
+#define        fast    sfast
+#define        slow    sslow
+#define        dissect sdissect
+#define        backref sbackref
+#define        step    sstep
+#define        print   sprint
+#define        at      sat
+#define        match   smat
+#endif
+#ifdef LNAMES
+#define        matcher lmatcher
+#define        fast    lfast
+#define        slow    lslow
+#define        dissect ldissect
+#define        backref lbackref
+#define        step    lstep
+#define        print   lprint
+#define        at      lat
+#define        match   lmat
+#endif
+
+/* another structure passed up and down to avoid zillions of parameters */
+struct match {
+       struct re_guts *g;
+       int eflags;
+       regmatch_t *pmatch;     /* [nsub+1] (0 element unused) */
+       char *offp;             /* offsets work from here */
+       char *beginp;           /* start of string -- virtual NUL precedes */
+       char *endp;             /* end of string -- virtual NUL here */
+       char *coldp;            /* can be no match starting before here */
+       char **lastpos;         /* [nplus+1] */
+       STATEVARS;
+       states st;              /* current states */
+       states fresh;           /* states for a fresh start */
+       states tmp;             /* temporary */
+       states empty;           /* empty set of states */
+};
+
+#include "engine.ih"
+
+#ifdef REDEBUG
+#define        SP(t, s, c)     print(m, t, s, c, stdout)
+#define        AT(t, p1, p2, s1, s2)   at(m, t, p1, p2, s1, s2)
+#define        NOTE(str)       { if (m->eflags&REG_TRACE) printf("=%s\n", (str)); }
+#else
+#define        SP(t, s, c)     /* nothing */
+#define        AT(t, p1, p2, s1, s2)   /* nothing */
+#define        NOTE(s) /* nothing */
+#endif
+
+/*
+ - matcher - the actual matching engine
+ == static int matcher(register struct re_guts *g, char *string, \
+ ==    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;
+char *string;
+size_t nmatch;
+regmatch_t pmatch[];
+int eflags;
+{
+       register char *endp;
+       register int i;
+       struct match mv;
+       register struct match *m = &mv;
+       register char *dp;
+       const register sopno gf = g->firststate+1;      /* +1 for OEND */
+       const register sopno gl = g->laststate;
+       char *start;
+       char *stop;
+
+       /* simplify the situation where possible */
+       if (g->cflags&REG_NOSUB)
+               nmatch = 0;
+       if (eflags&REG_STARTEND) {
+               start = string + pmatch[0].rm_so;
+               stop = string + pmatch[0].rm_eo;
+       } else {
+               start = string;
+               stop = start + strlen(start);
+       }
+       if (stop < start)
+               return(REG_INVARG);
+
+       /* 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)
+                               break;
+               if (dp == stop)         /* we didn't find g->must */
+                       return(REG_NOMATCH);
+       }
+
+       /* match struct setup */
+       m->g = g;
+       m->eflags = eflags;
+       m->pmatch = NULL;
+       m->lastpos = NULL;
+       m->offp = string;
+       m->beginp = start;
+       m->endp = stop;
+       STATESETUP(m, 4);
+       SETUP(m->st);
+       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 */
+                       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);
+                       if (endp != NULL)
+                               break;
+                       assert(m->coldp < m->endp);
+                       m->coldp++;
+               }
+               if (nmatch == 1 && !g->backrefs)
+                       break;          /* no further info needed */
+
+               /* oh my, he wants the subexpressions... */
+               if (m->pmatch == NULL)
+                       m->pmatch = (regmatch_t *)malloc((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;
+               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 = (char **)malloc((g->nplus+1) *
+                                                       sizeof(char *));
+                       if (g->nplus > 0 && m->lastpos == NULL) {
+                               free(m->pmatch);
+                               STATETEARDOWN(m);
+                               return(REG_ESPACE);
+                       }
+                       NOTE("backref dissect");
+                       dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+               }
+               if (dp != NULL)
+                       break;
+
+               /* uh-oh... we couldn't find a subexpression-level match */
+               assert(g->backrefs);    /* must be back references doing it */
+               assert(g->nplus == 0 || m->lastpos != NULL);
+               for (;;) {
+                       if (dp != NULL || endp <= m->coldp)
+                               break;          /* defeat */
+                       NOTE("backoff");
+                       endp = slow(m, m->coldp, endp-1, gf, gl);
+                       if (endp == NULL)
+                               break;          /* defeat */
+                       /* try it on a shorter possibility */
+#ifndef NDEBUG
+                       for (i = 1; i <= m->g->nsub; i++) {
+                               assert(m->pmatch[i].rm_so == -1);
+                               assert(m->pmatch[i].rm_eo == -1);
+                       }
+#endif
+                       NOTE("backoff dissect");
+                       dp = backref(m, m->coldp, endp, gf, gl, (sopno)0);
+               }
+               assert(dp == NULL || dp == endp);
+               if (dp != NULL)         /* found a shorter one */
+                       break;
+
+               /* despite initial appearances, there is no match here */
+               NOTE("false alarm");
+               start = m->coldp + 1;   /* recycle starting later */
+               assert(start <= stop);
+       }
+
+       /* fill in the details if requested */
+       if (nmatch > 0) {
+               pmatch[0].rm_so = m->coldp - m->offp;
+               pmatch[0].rm_eo = endp - m->offp;
+       }
+       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;
+                       }
+       }
+
+       if (m->pmatch != NULL)
+               free((char *)m->pmatch);
+       if (m->lastpos != NULL)
+               free((char *)m->lastpos);
+       STATETEARDOWN(m);
+       return(0);
+}
+
+/*
+ - dissect - figure out what matched what, no back references
+ == static char *dissect(register struct match *m, char *start, \
+ ==    char *stop, sopno startst, sopno stopst);
+ */
+static char *                  /* == stop (success) always */
+dissect(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+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 */
+       register char *sp;      /* start of string matched by it */
+       register char *stp;     /* string matched by it cannot pass here */
+       register char *rest;    /* start of rest of string */
+       register char *tail;    /* string unmatched by rest of RE */
+       register sopno ssub;    /* start sop of subsubRE */
+       register sopno esub;    /* end sop of subsubRE */
+       register char *ssp;     /* start of string matched by subsubRE */
+       register char *sep;     /* end of string matched by subsubRE */
+       register char *oldssp;  /* previous ssp */
+       register char *dp;
+
+       AT("diss", start, stop, startst, stopst);
+       sp = start;
+       for (ss = startst; ss < stopst; ss = es) {
+               /* identify end of subRE */
+               es = ss;
+               switch (OP(m->g->strip[es])) {
+               case OPLUS_:
+               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]);
+                       break;
+               }
+               es++;
+
+               /* 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;
+                       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);
+                               if (tail == stop)
+                                       break;          /* yes! */
+                               /* no -- try a shorter match for this one */
+                               stp = rest - 1;
+                               assert(stp >= sp);      /* it did work */
+                       }
+                       ssub = ss + 1;
+                       esub = es - 1;
+                       /* did innards match? */
+                       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 (;;) {
+                               /* 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);
+                               if (tail == stop)
+                                       break;          /* yes! */
+                               /* no -- try a shorter match for this one */
+                               stp = rest - 1;
+                               assert(stp >= sp);      /* it did work */
+                       }
+                       ssub = ss + 1;
+                       esub = es - 1;
+                       ssp = sp;
+                       oldssp = ssp;
+                       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;
+                       }
+                       if (sep == NULL) {
+                               /* last successful match */
+                               sep = ssp;
+                               ssp = oldssp;
+                       }
+                       assert(sep == rest);    /* must exhaust substring */
+                       assert(slow(m, ssp, sep, ssub, esub) == rest);
+                       dp = dissect(m, ssp, sep, ssub, esub);
+                       assert(dp == sep);
+                       sp = rest;
+                       break;
+               case OCH_:
+                       stp = stop;
+                       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);
+                               if (tail == stop)
+                                       break;          /* yes! */
+                               /* no -- try a shorter match for this one */
+                               stp = rest - 1;
+                               assert(stp >= sp);      /* it did work */
+                       }
+                       ssub = ss + 1;
+                       esub = ss + OPND(m->g->strip[ss]) - 1;
+                       assert(OP(m->g->strip[esub]) == OOR1);
+                       for (;;) {      /* find first matching branch */
+                               if (slow(m, sp, rest, ssub, esub) == rest)
+                                       break;  /* it matched all of it */
+                               /* that one missed, try next one */
+                               assert(OP(m->g->strip[esub]) == OOR1);
+                               esub++;
+                               assert(OP(m->g->strip[esub]) == OOR2);
+                               ssub = esub + 1;
+                               esub += OPND(m->g->strip[esub]);
+                               if (OP(m->g->strip[esub]) == OOR2)
+                                       esub--;
+                               else
+                                       assert(OP(m->g->strip[esub]) == O_CH);
+                       }
+                       dp = dissect(m, sp, rest, ssub, esub);
+                       assert(dp == rest);
+                       sp = rest;
+                       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]);
+                       assert(0 < i && i <= m->g->nsub);
+                       m->pmatch[i].rm_so = sp - m->offp;
+                       break;
+               case ORPAREN:
+                       i = OPND(m->g->strip[ss]);
+                       assert(0 < i && i <= m->g->nsub);
+                       m->pmatch[i].rm_eo = sp - m->offp;
+                       break;
+               default:                /* uh oh */
+                       assert(nope);
+                       break;
+               }
+       }
+
+       assert(sp == stop);
+       return(sp);
+}
+
+/*
+ - backref - figure out what matched what, figuring in back references
+ == static char *backref(register struct match *m, char *start, \
+ ==    char *stop, sopno startst, sopno stopst, sopno lev);
+ */
+static char *                  /* == stop (success) or NULL (failure) */
+backref(m, start, stop, startst, stopst, lev)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+sopno lev;                     /* PLUS nesting level */
+{
+       register int i;
+       register sopno ss;      /* start sop of current subRE */
+       register char *sp;      /* start of string matched by it */
+       register sopno ssub;    /* start sop of subsubRE */
+       register sopno esub;    /* end sop of subsubRE */
+       register char *ssp;     /* start of string matched by subsubRE */
+       register char *dp;
+       register size_t len;
+       register int hard;
+       register sop s;
+       register regoff_t offsave;
+       register cset *cs;
+
+       AT("back", start, stop, startst, stopst);
+       sp = start;
+
+       /* get as far as we can with easy stuff */
+       hard = 0;
+       for (ss = startst; !hard && ss < stopst; ss++)
+               switch (OP(s = m->g->strip[ss])) {
+               case OCHAR:
+                       if (sp == stop || *sp++ != (char)OPND(s))
+                               return(NULL);
+                       break;
+               case OANY:
+                       if (sp == stop)
+                               return(NULL);
+                       sp++;
+                       break;
+               case OANYOF:
+                       cs = &m->g->sets[OPND(s)];
+                       if (sp == stop || !CHIN(cs, *sp++))
+                               return(NULL);
+                       break;
+               case OBOL:
+                       if ( (sp == m->beginp && !(m->eflags&REG_NOTBOL)) ||
+                                       (sp < m->endp && *(sp-1) == '\n' &&
+                                               (m->g->cflags&REG_NEWLINE)) )
+                               { /* yes */ }
+                       else
+                               return(NULL);
+                       break;
+               case OEOL:
+                       if ( (sp == m->endp && !(m->eflags&REG_NOTEOL)) ||
+                                       (sp < m->endp && *sp == '\n' &&
+                                               (m->g->cflags&REG_NEWLINE)) )
+                               { /* yes */ }
+                       else
+                               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
+                               return(NULL);
+                       break;
+               case OEOW:
+                       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
+                               return(NULL);
+                       break;
+               case O_QUEST:
+                       break;
+               case OOR1:      /* matches null but needs to skip */
+                       ss++;
+                       s = m->g->strip[ss];
+                       do {
+                               assert(OP(s) == OOR2);
+                               ss += OPND(s);
+                       } while (OP(s = m->g->strip[ss]) != O_CH);
+                       /* note that the ss++ gets us past the O_CH */
+                       break;
+               default:        /* have to make a choice */
+                       hard = 1;
+                       break;
+               }
+       if (!hard) {            /* that was it! */
+               if (sp != stop)
+                       return(NULL);
+               return(sp);
+       }
+       ss--;                   /* adjust for the for's final increment */
+
+       /* the hard stuff */
+       AT("hard", sp, stop, ss, stopst);
+       s = m->g->strip[ss];
+       switch (OP(s)) {
+       case OBACK_:            /* the vilest depths */
+               i = OPND(s);
+               assert(0 < i && i <= m->g->nsub);
+               if (m->pmatch[i].rm_eo == -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);
+               if (sp > stop - len)
+                       return(NULL);   /* not enough left to match */
+               ssp = m->offp + 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));
+               /* try another pass */
+               m->lastpos[lev] = sp;
+               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;
+       case OCH_:              /* find the right one, if any */
+               ssub = ss + 1;
+               esub = ss + OPND(s) - 1;
+               assert(OP(m->g->strip[esub]) == OOR1);
+               for (;;) {      /* find first matching branch */
+                       dp = backref(m, sp, stop, ssub, esub, lev);
+                       if (dp != NULL)
+                               return(dp);
+                       /* that one missed, try next one */
+                       if (OP(m->g->strip[esub]) == O_CH)
+                               return(NULL);   /* there is none */
+                       esub++;
+                       assert(OP(m->g->strip[esub]) == OOR2);
+                       ssub = esub + 1;
+                       esub += OPND(m->g->strip[esub]);
+                       if (OP(m->g->strip[esub]) == OOR2)
+                               esub--;
+                       else
+                               assert(OP(m->g->strip[esub]) == O_CH);
+               }
+               break;
+       case OLPAREN:           /* must undo assignment if rest fails */
+               i = OPND(s);
+               assert(0 < i && i <= m->g->nsub);
+               offsave = m->pmatch[i].rm_so;
+               m->pmatch[i].rm_so = 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);
+               assert(0 < i && i <= m->g->nsub);
+               offsave = m->pmatch[i].rm_eo;
+               m->pmatch[i].rm_eo = 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((char *)NULL);   /* dummy */
+}
+
+/*
+ - fast - step through the string at top speed
+ == static char *fast(register struct match *m, char *start, \
+ ==    char *stop, sopno startst, sopno stopst);
+ */
+static char *                  /* where tentative match ended, or NULL */
+fast(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+       register states st = m->st;
+       register states fresh = m->fresh;
+       register states tmp = m->tmp;
+       register char *p = start;
+       register int c = (start == m->beginp) ? OUT : *(start-1);
+       register int lastc;     /* previous c */
+       register int flagch;
+       register int i;
+       register char *coldp;   /* last p after which no match was underway */
+
+       CLEAR(st);
+       SET1(st, startst);
+       st = step(m->g, startst, stopst, st, NOTHING, st);
+       ASSIGN(fresh, st);
+       SP("start", st, *p);
+       coldp = NULL;
+       for (;;) {
+               /* next character */
+               lastc = c;
+               c = (p == m->endp) ? OUT : *p;
+               if (EQ(st, fresh))
+                       coldp = p;
+
+               /* is there an EOL and/or BOL between lastc and c? */
+               flagch = '\0';
+               i = 0;
+               if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+                               (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+                       flagch = BOL;
+                       i = m->g->nbol;
+               }
+               if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+                               (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+                       flagch = (flagch == BOL) ? BOLEOL : EOL;
+                       i += m->g->neol;
+               }
+               if (i != 0) {
+                       for (; i > 0; i--)
+                               st = step(m->g, startst, stopst, st, flagch, st);
+                       SP("boleol", st, c);
+               }
+
+               /* how about a word boundary? */
+               if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+                                       (c != OUT && ISWORD(c)) ) {
+                       flagch = BOW;
+               }
+               if ( (lastc != OUT && ISWORD(lastc)) &&
+                               (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+                       flagch = EOW;
+               }
+               if (flagch == BOW || flagch == EOW) {
+                       st = step(m->g, startst, stopst, st, flagch, st);
+                       SP("boweow", st, c);
+               }
+
+               /* are we done? */
+               if (ISSET(st, stopst) || p == stop)
+                       break;          /* NOTE BREAK OUT */
+
+               /* no, we must deal with this character */
+               ASSIGN(tmp, st);
+               ASSIGN(st, fresh);
+               assert(c != OUT);
+               st = step(m->g, startst, stopst, tmp, c, st);
+               SP("aft", st, c);
+               assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+               p++;
+       }
+
+       assert(coldp != NULL);
+       m->coldp = coldp;
+       if (ISSET(st, stopst))
+               return(p+1);
+       else
+               return(NULL);
+}
+
+/*
+ - slow - step through the string more deliberately
+ == static char *slow(register struct match *m, char *start, \
+ ==    char *stop, sopno startst, sopno stopst);
+ */
+static char *                  /* where it ended */
+slow(m, start, stop, startst, stopst)
+register struct match *m;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+       register states st = m->st;
+       register states empty = m->empty;
+       register states tmp = m->tmp;
+       register char *p = start;
+       register int c = (start == m->beginp) ? OUT : *(start-1);
+       register int lastc;     /* previous c */
+       register int flagch;
+       register int i;
+       register char *matchp;  /* last p at which a match ended */
+
+       AT("slow", start, stop, startst, stopst);
+       CLEAR(st);
+       SET1(st, startst);
+       SP("sstart", st, *p);
+       st = step(m->g, startst, stopst, st, NOTHING, st);
+       matchp = NULL;
+       for (;;) {
+               /* next character */
+               lastc = c;
+               c = (p == m->endp) ? OUT : *p;
+
+               /* is there an EOL and/or BOL between lastc and c? */
+               flagch = '\0';
+               i = 0;
+               if ( (lastc == '\n' && m->g->cflags&REG_NEWLINE) ||
+                               (lastc == OUT && !(m->eflags&REG_NOTBOL)) ) {
+                       flagch = BOL;
+                       i = m->g->nbol;
+               }
+               if ( (c == '\n' && m->g->cflags&REG_NEWLINE) ||
+                               (c == OUT && !(m->eflags&REG_NOTEOL)) ) {
+                       flagch = (flagch == BOL) ? BOLEOL : EOL;
+                       i += m->g->neol;
+               }
+               if (i != 0) {
+                       for (; i > 0; i--)
+                               st = step(m->g, startst, stopst, st, flagch, st);
+                       SP("sboleol", st, c);
+               }
+
+               /* how about a word boundary? */
+               if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) &&
+                                       (c != OUT && ISWORD(c)) ) {
+                       flagch = BOW;
+               }
+               if ( (lastc != OUT && ISWORD(lastc)) &&
+                               (flagch == EOL || (c != OUT && !ISWORD(c))) ) {
+                       flagch = EOW;
+               }
+               if (flagch == BOW || flagch == EOW) {
+                       st = step(m->g, startst, stopst, st, flagch, st);
+                       SP("sboweow", st, c);
+               }
+
+               /* are we done? */
+               if (ISSET(st, stopst))
+                       matchp = p;
+               if (EQ(st, empty) || p == stop)
+                       break;          /* NOTE BREAK OUT */
+
+               /* no, we must deal with this character */
+               ASSIGN(tmp, st);
+               ASSIGN(st, empty);
+               assert(c != OUT);
+               st = step(m->g, startst, stopst, tmp, c, st);
+               SP("saft", st, c);
+               assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st));
+               p++;
+       }
+
+       return(matchp);
+}
+
+
+/*
+ - step - map set of states reachable before char to set reachable after
+ == static states step(register struct re_guts *g, sopno start, sopno stop, \
+ ==    register states bef, int ch, register states aft);
+ == #define    BOL     (OUT+1)
+ == #define    EOL     (BOL+1)
+ == #define    BOLEOL  (BOL+2)
+ == #define    NOTHING (BOL+3)
+ == #define    BOW     (BOL+4)
+ == #define    EOW     (BOL+5)
+ == #define    CODEMAX (BOL+5)         // highest code used
+ == #define    NONCHAR(c)      ((c) > CHAR_MAX)
+ == #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 */
+{
+       register cset *cs;
+       register sop s;
+       register sopno pc;
+       register onestate here;         /* note, macros know this name */
+       register sopno look;
+       register long i;
+
+       for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) {
+               s = g->strip[pc];
+               switch (OP(s)) {
+               case OEND:
+                       assert(pc == stop-1);
+                       break;
+               case OCHAR:
+                       /* only characters can match */
+                       assert(!NONCHAR(ch) || ch != (char)OPND(s));
+                       if (ch == (char)OPND(s))
+                               FWD(aft, bef, 1);
+                       break;
+               case OBOL:
+                       if (ch == BOL || ch == BOLEOL)
+                               FWD(aft, bef, 1);
+                       break;
+               case OEOL:
+                       if (ch == EOL || ch == BOLEOL)
+                               FWD(aft, bef, 1);
+                       break;
+               case OBOW:
+                       if (ch == BOW)
+                               FWD(aft, bef, 1);
+                       break;
+               case OEOW:
+                       if (ch == EOW)
+                               FWD(aft, bef, 1);
+                       break;
+               case OANY:
+                       if (!NONCHAR(ch))
+                               FWD(aft, bef, 1);
+                       break;
+               case OANYOF:
+                       cs = &g->sets[OPND(s)];
+                       if (!NONCHAR(ch) && CHIN(cs, ch))
+                               FWD(aft, bef, 1);
+                       break;
+               case OBACK_:            /* ignored here */
+               case O_BACK:
+                       FWD(aft, aft, 1);
+                       break;
+               case OPLUS_:            /* forward, this is just an empty */
+                       FWD(aft, aft, 1);
+                       break;
+               case O_PLUS:            /* both forward and back */
+                       FWD(aft, aft, 1);
+                       i = ISSETBACK(aft, OPND(s));
+                       BACK(aft, aft, OPND(s));
+                       if (!i && ISSETBACK(aft, OPND(s))) {
+                               /* oho, must reconsider loop body */
+                               pc -= OPND(s) + 1;
+                               INIT(here, pc);
+                       }
+                       break;
+               case OQUEST_:           /* two branches, both forward */
+                       FWD(aft, aft, 1);
+                       FWD(aft, aft, OPND(s));
+                       break;
+               case O_QUEST:           /* just an empty */
+                       FWD(aft, aft, 1);
+                       break;
+               case OLPAREN:           /* not significant here */
+               case ORPAREN:
+                       FWD(aft, aft, 1);
+                       break;
+               case OCH_:              /* mark the first two branches */
+                       FWD(aft, aft, 1);
+                       assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+                       FWD(aft, aft, OPND(s));
+                       break;
+               case OOR1:              /* done a branch, find the O_CH */
+                       if (ISSTATEIN(aft, here)) {
+                               for (look = 1;
+                                               OP(s = g->strip[pc+look]) != O_CH;
+                                               look += OPND(s))
+                                       assert(OP(s) == OOR2);
+                               FWD(aft, aft, look);
+                       }
+                       break;
+               case OOR2:              /* propagate OCH_'s marking */
+                       FWD(aft, aft, 1);
+                       if (OP(g->strip[pc+OPND(s)]) != O_CH) {
+                               assert(OP(g->strip[pc+OPND(s)]) == OOR2);
+                               FWD(aft, aft, OPND(s));
+                       }
+                       break;
+               case O_CH:              /* just empty */
+                       FWD(aft, aft, 1);
+                       break;
+               default:                /* ooooops... */
+                       assert(nope);
+                       break;
+               }
+       }
+
+       return(aft);
+}
+
+#ifdef REDEBUG
+/*
+ - print - print a set of states
+ == #ifdef REDEBUG
+ == static void print(struct match *m, char *caption, states st, \
+ ==    int ch, FILE *d);
+ == #endif
+ */
+static void
+print(m, caption, st, ch, d)
+struct match *m;
+char *caption;
+states st;
+int ch;
+FILE *d;
+{
+       register struct re_guts *g = m->g;
+       register int i;
+       register int first = 1;
+
+       if (!(m->eflags&REG_TRACE))
+               return;
+
+       fprintf(d, "%s", caption);
+       if (ch != '\0')
+               fprintf(d, " %s", pchar(ch));
+       for (i = 0; i < g->nstates; i++)
+               if (ISSET(st, i)) {
+                       fprintf(d, "%s%d", (first) ? "\t" : ", ", i);
+                       first = 0;
+               }
+       fprintf(d, "\n");
+}
+
+/* 
+ - at - print current situation
+ == #ifdef REDEBUG
+ == static void at(struct match *m, char *title, char *start, char *stop, \
+ ==                                            sopno startst, sopno stopst);
+ == #endif
+ */
+static void
+at(m, title, start, stop, startst, stopst)
+struct match *m;
+char *title;
+char *start;
+char *stop;
+sopno startst;
+sopno stopst;
+{
+       if (!(m->eflags&REG_TRACE))
+               return;
+
+       printf("%s %s-", title, pchar(*start));
+       printf("%s ", pchar(*stop));
+       printf("%ld-%ld\n", (long)startst, (long)stopst);
+}
+
+#ifndef PCHARDONE
+#define        PCHARDONE       /* never again */
+/*
+ - pchar - make a character printable
+ == #ifdef REDEBUG
+ == static char *pchar(int ch);
+ == #endif
+ *
+ * Is this identical to regchar() over in debug.c?  Well, yes.  But a
+ * duplicate here avoids having a debugging-capable regexec.o tied to
+ * a matching debug.o, and this is convenient.  It all disappears in
+ * the non-debug compilation anyway, so it doesn't matter much.
+ */
+static char *                  /* -> representation */
+pchar(ch)
+int ch;
+{
+       static char pbuf[10];
+
+       if (isprint(ch) || ch == ' ')
+               ap_snprintf(pbuf, sizeof(pbuf), "%c", ch);
+       else
+               ap_snprintf(pbuf, sizeof(pbuf), "\\%o", ch);
+       return(pbuf);
+}
+#endif
+#endif
+
+#undef matcher
+#undef fast
+#undef slow
+#undef dissect
+#undef backref
+#undef step
+#undef print
+#undef at
+#undef match
diff --git a/regex-src/fake/limits.h b/regex-src/fake/limits.h
new file mode 100644 (file)
index 0000000..94429e6
--- /dev/null
@@ -0,0 +1,4 @@
+#define        _POSIX2_RE_DUP_MAX      255
+#define        CHAR_MIN        (-128)
+#define        CHAR_MAX        127
+#define        CHAR_BIT        8
diff --git a/regex-src/fake/memmove.c b/regex-src/fake/memmove.c
new file mode 100644 (file)
index 0000000..daebcd0
--- /dev/null
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+/*
+ - memmove - fake ANSI C routine
+ */
+char *
+memmove(dst, src, count)
+char *dst;
+char *src;
+size_t count;
+{
+       register char *s;
+       register char *d;
+       register size_t n;
+
+       if (dst > src)
+               for (d = dst+count, s = src+count, n = count; n > 0; n--)
+                       *--d = *--s;
+       else
+               for (d = dst, s = src, n = count; n > 0; n--)
+                       *d++ = *s++;
+
+       return(dst);
+}
diff --git a/regex-src/fake/stdlib.h b/regex-src/fake/stdlib.h
new file mode 100644 (file)
index 0000000..34ac2ee
--- /dev/null
@@ -0,0 +1,2 @@
+extern char *malloc();
+extern char *realloc();
diff --git a/regex-src/main.c b/regex-src/main.c
new file mode 100644 (file)
index 0000000..1785df3
--- /dev/null
@@ -0,0 +1,515 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <regex.h>
+#include <assert.h>
+
+#include "main.ih"
+
+char *progname;
+int debug = 0;
+int line = 0;
+int status = 0;
+
+int copts = REG_EXTENDED;
+int eopts = 0;
+regoff_t startoff = 0;
+regoff_t endoff = 0;
+
+
+extern int split();
+extern void regprint();
+
+/*
+ - main - do the simple case, hand off to regress() for regression
+ */
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       regex_t re;
+#      define  NS      10
+       regmatch_t subs[NS];
+       char erbuf[100];
+       int err;
+       size_t len;
+       int c;
+       int errflg = 0;
+       register int i;
+       extern int optind;
+       extern char *optarg;
+
+       progname = argv[0];
+
+       while ((c = getopt(argc, argv, "c:e:S:E:x")) != EOF)
+               switch (c) {
+               case 'c':       /* compile options */
+                       copts = options('c', optarg);
+                       break;
+               case 'e':       /* execute options */
+                       eopts = options('e', optarg);
+                       break;
+               case 'S':       /* start offset */
+                       startoff = (regoff_t)atoi(optarg);
+                       break;
+               case 'E':       /* end offset */
+                       endoff = (regoff_t)atoi(optarg);
+                       break;
+               case 'x':       /* Debugging. */
+                       debug++;
+                       break;
+               case '?':
+               default:
+                       errflg++;
+                       break;
+               }
+       if (errflg) {
+               fprintf(stderr, "usage: %s ", progname);
+               fprintf(stderr, "[-c copt][-C][-d] [re]\n");
+               exit(2);
+       }
+
+       if (optind >= argc) {
+               regress(stdin);
+               exit(status);
+       }
+
+       err = regcomp(&re, argv[optind++], copts);
+       if (err) {
+               len = regerror(err, &re, erbuf, sizeof(erbuf));
+               fprintf(stderr, "error %s, %d/%d `%s'\n",
+                       eprint(err), len, sizeof(erbuf), erbuf);
+               exit(status);
+       }
+       regprint(&re, stdout);  
+
+       if (optind >= argc) {
+               regfree(&re);
+               exit(status);
+       }
+
+       if (eopts&REG_STARTEND) {
+               subs[0].rm_so = startoff;
+               subs[0].rm_eo = strlen(argv[optind]) - endoff;
+       }
+       err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
+       if (err) {
+               len = regerror(err, &re, erbuf, sizeof(erbuf));
+               fprintf(stderr, "error %s, %d/%d `%s'\n",
+                       eprint(err), len, sizeof(erbuf), erbuf);
+               exit(status);
+       }
+       if (!(copts&REG_NOSUB)) {
+               len = (int)(subs[0].rm_eo - subs[0].rm_so);
+               if (subs[0].rm_so != -1) {
+                       if (len != 0)
+                               printf("match `%.*s'\n", len,
+                                       argv[optind] + subs[0].rm_so);
+                       else
+                               printf("match `'@%.1s\n",
+                                       argv[optind] + subs[0].rm_so);
+               }
+               for (i = 1; i < NS; i++)
+                       if (subs[i].rm_so != -1)
+                               printf("(%d) `%.*s'\n", i,
+                                       (int)(subs[i].rm_eo - subs[i].rm_so),
+                                       argv[optind] + subs[i].rm_so);
+       }
+       exit(status);
+}
+
+/*
+ - regress - main loop of regression test
+ == void regress(FILE *in);
+ */
+void
+regress(in)
+FILE *in;
+{
+       char inbuf[1000];
+#      define  MAXF    10
+       char *f[MAXF];
+       int nf;
+       int i;
+       char erbuf[100];
+       size_t ne;
+       char *badpat = "invalid regular expression";
+#      define  SHORT   10
+       char *bpname = "REG_BADPAT";
+       regex_t re;
+
+       while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
+               line++;
+               if (inbuf[0] == '#' || inbuf[0] == '\n')
+                       continue;                       /* NOTE CONTINUE */
+               inbuf[strlen(inbuf)-1] = '\0';  /* get rid of stupid \n */
+               if (debug)
+                       fprintf(stdout, "%d:\n", line);
+               nf = split(inbuf, f, MAXF, "\t\t");
+               if (nf < 3) {
+                       fprintf(stderr, "bad input, line %d\n", line);
+                       exit(1);
+               }
+               for (i = 0; i < nf; i++)
+                       if (strcmp(f[i], "\"\"") == 0)
+                               f[i] = "";
+               if (nf <= 3)
+                       f[3] = NULL;
+               if (nf <= 4)
+                       f[4] = NULL;
+               try(f[0], f[1], f[2], f[3], f[4], options('c', f[1]));
+               if (opt('&', f[1]))     /* try with either type of RE */
+                       try(f[0], f[1], f[2], f[3], f[4],
+                                       options('c', f[1]) &~ REG_EXTENDED);
+       }
+
+       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);
+               status = 1;
+       }
+       ne = regerror(REG_BADPAT, (regex_t *)NULL, erbuf, (size_t)SHORT);
+       if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' ||
+                                               ne != strlen(badpat)+1) {
+               fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n",
+                                               erbuf, SHORT-1, badpat);
+               status = 1;
+       }
+       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));
+       if (atoi(erbuf) != (int)REG_BADPAT) {
+               fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
+                                               erbuf, (long)REG_BADPAT);
+               status = 1;
+       } else if (ne != strlen(erbuf)+1) {
+               fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n",
+                                               erbuf, (long)REG_BADPAT);
+               status = 1;
+       }
+}
+
+/*
+ - try - try it, and report on problems
+ == void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts);
+ */
+void
+try(f0, f1, f2, f3, f4, opts)
+char *f0;
+char *f1;
+char *f2;
+char *f3;
+char *f4;
+int opts;                      /* may not match f1 */
+{
+       regex_t re;
+#      define  NSUBS   10
+       regmatch_t subs[NSUBS];
+#      define  NSHOULD 15
+       char *should[NSHOULD];
+       int nshould;
+       char erbuf[100];
+       int err;
+       int len;
+       char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
+       register int i;
+       char *grump;
+       char f0copy[1000];
+       char f2copy[1000];
+
+       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));
+               fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
+                                       line, type, eprint(err), len,
+                                       sizeof(erbuf), erbuf);
+               status = 1;
+       } else if (err == 0 && opt('C', f1)) {
+               /* unexpected success */
+               fprintf(stderr, "%d: %s should have given REG_%s\n",
+                                               line, type, f2);
+               status = 1;
+               err = 1;        /* so we won't try regexec */
+       }
+
+       if (err != 0) {
+               regfree(&re);
+               return;
+       }
+
+       strncpy(f2copy, f2, sizeof(f2copy)-1);
+       f2copy[sizeof(f2copy)-1] = '\0';
+       fixstr(f2copy);
+
+       if (options('e', f1)&REG_STARTEND) {
+               if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL)
+                       fprintf(stderr, "%d: bad STARTEND syntax\n", line);
+               subs[0].rm_so = strchr(f2, '(') - f2 + 1;
+               subs[0].rm_eo = strchr(f2, ')') - f2;
+       }
+       err = regexec(&re, f2copy, NSUBS, subs, options('e', f1));
+
+       if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
+               /* unexpected error or wrong error */
+               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);
+               status = 1;
+       } else if (err != 0) {
+               /* nothing more to check */
+       } else if (f3 == NULL) {
+               /* unexpected success */
+               fprintf(stderr, "%d: %s exec should have failed\n",
+                                               line, type);
+               status = 1;
+               err = 1;                /* just on principle */
+       } else if (opts&REG_NOSUB) {
+               /* nothing more to check */
+       } else if ((grump = check(f2, subs[0], f3)) != NULL) {
+               fprintf(stderr, "%d: %s %s\n", line, type, grump);
+               status = 1;
+               err = 1;
+       }
+
+       if (err != 0 || f4 == NULL) {
+               regfree(&re);
+               return;
+       }
+
+       for (i = 1; i < NSHOULD; i++)
+               should[i] = NULL;
+       nshould = split(f4, should+1, NSHOULD-1, ",");
+       if (nshould == 0) {
+               nshould = 1;
+               should[1] = "";
+       }
+       for (i = 1; i < NSUBS; i++) {
+               grump = check(f2, subs[i], should[i]);
+               if (grump != NULL) {
+                       fprintf(stderr, "%d: %s $%d %s\n", line,
+                                                       type, i, grump);
+                       status = 1;
+                       err = 1;
+               }
+       }
+
+       regfree(&re);
+}
+
+/*
+ - options - pick options out of a regression-test string
+ == int options(int type, char *s);
+ */
+int
+options(type, s)
+int type;                      /* 'c' compile, 'e' exec */
+char *s;
+{
+       register char *p;
+       register int o = (type == 'c') ? copts : eopts;
+       register char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
+
+       for (p = s; *p != '\0'; p++)
+               if (strchr(legal, *p) != NULL)
+                       switch (*p) {
+                       case 'b':
+                               o &= ~REG_EXTENDED;
+                               break;
+                       case 'i':
+                               o |= REG_ICASE;
+                               break;
+                       case 's':
+                               o |= REG_NOSUB;
+                               break;
+                       case 'n':
+                               o |= REG_NEWLINE;
+                               break;
+                       case 'm':
+                               o &= ~REG_EXTENDED;
+                               o |= REG_NOSPEC;
+                               break;
+                       case 'p':
+                               o |= REG_PEND;
+                               break;
+                       case '^':
+                               o |= REG_NOTBOL;
+                               break;
+                       case '$':
+                               o |= REG_NOTEOL;
+                               break;
+                       case '#':
+                               o |= REG_STARTEND;
+                               break;
+                       case 't':       /* trace */
+                               o |= REG_TRACE;
+                               break;
+                       case 'l':       /* force long representation */
+                               o |= REG_LARGE;
+                               break;
+                       case 'r':       /* force backref use */
+                               o |= REG_BACKR;
+                               break;
+                       }
+       return(o);
+}
+
+/*
+ - opt - is a particular option in a regression string?
+ == int opt(int c, char *s);
+ */
+int                            /* predicate */
+opt(c, s)
+int c;
+char *s;
+{
+       return(strchr(s, c) != NULL);
+}
+
+/*
+ - fixstr - transform magic characters in strings
+ == void fixstr(register char *p);
+ */
+void
+fixstr(p)
+register char *p;
+{
+       if (p == NULL)
+               return;
+
+       for (; *p != '\0'; p++)
+               if (*p == 'N')
+                       *p = '\n';
+               else if (*p == 'T')
+                       *p = '\t';
+               else if (*p == 'S')
+                       *p = ' ';
+               else if (*p == 'Z')
+                       *p = '\0';
+}
+
+/*
+ - check - check a substring match
+ == char *check(char *str, regmatch_t sub, char *should);
+ */
+char *                         /* NULL or complaint */
+check(str, sub, should)
+char *str;
+regmatch_t sub;
+char *should;
+{
+       register int len;
+       register int shlen;
+       register char *p;
+       static char grump[500];
+       register char *at = NULL;
+
+       if (should != NULL && strcmp(should, "-") == 0)
+               should = NULL;
+       if (should != NULL && should[0] == '@') {
+               at = should + 1;
+               should = "";
+       }
+
+       /* check rm_so and rm_eo for consistency */
+       if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) ||
+                               (sub.rm_so != -1 && sub.rm_eo == -1) ||
+                               (sub.rm_so != -1 && sub.rm_so < 0) ||
+                               (sub.rm_eo != -1 && sub.rm_eo < 0) ) {
+               ap_snprintf(grump, sizeof(grump),
+                           "start %ld end %ld", (long)sub.rm_so,
+                           (long)sub.rm_eo);
+               return(grump);
+       }
+
+       /* check for no match */
+       if (sub.rm_so == -1 && should == NULL)
+               return(NULL);
+       if (sub.rm_so == -1)
+               return("did not match");
+
+       /* check for in range */
+       if (sub.rm_eo > strlen(str)) {
+               ap_snprintf(grump, sizeof(grump),
+                           "start %ld end %ld, past end of string",
+                           (long)sub.rm_so, (long)sub.rm_eo);
+               return(grump);
+       }
+
+       len = (int)(sub.rm_eo - sub.rm_so);
+       shlen = (int)strlen(should);
+       p = str + sub.rm_so;
+
+       /* check for not supposed to match */
+       if (should == NULL) {
+               ap_snprintf(grump, sizeof(grump), "matched `%.*s'", len, p);
+               return(grump);
+       }
+
+       /* check for wrong match */
+       if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
+               ap_snprintf(grump, sizeof(grump),
+                           "matched `%.*s' instead", len, p);
+               return(grump);
+       }
+       if (shlen > 0)
+               return(NULL);
+
+       /* check null match in right place */
+       if (at == NULL)
+               return(NULL);
+       shlen = strlen(at);
+       if (shlen == 0)
+               shlen = 1;      /* force check for end-of-string */
+       if (strncmp(p, at, shlen) != 0) {
+               ap_snprintf(grump, sizeof(grump), "matched null at `%.20s'", p);
+               return(grump);
+       }
+       return(NULL);
+}
+
+/*
+ - eprint - convert error number to name
+ == static char *eprint(int err);
+ */
+static char *
+eprint(err)
+int err;
+{
+       static char epbuf[100];
+       size_t len;
+
+       len = regerror(REG_ITOA|err, (regex_t *)NULL, epbuf, sizeof(epbuf));
+       assert(len <= sizeof(epbuf));
+       return(epbuf);
+}
+
+/*
+ - efind - convert error name to number
+ == static int efind(char *name);
+ */
+static int
+efind(name)
+char *name;
+{
+       static char efbuf[100];
+       size_t n;
+       regex_t re;
+
+       ap_snprintf(efbuf, sizeof(efbuf), "REG_%s", name);
+       assert(strlen(efbuf) < sizeof(efbuf));
+       re.re_endp = efbuf;
+       (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
+       return(atoi(efbuf));
+}
diff --git a/regex-src/mkh b/regex-src/mkh
new file mode 100644 (file)
index 0000000..252b246
--- /dev/null
@@ -0,0 +1,76 @@
+#! /bin/sh
+# mkh - pull headers out of C source
+PATH=/bin:/usr/bin ; export PATH
+
+# egrep pattern to pick out marked lines
+egrep='^ =([   ]|$)'
+
+# Sed program to process marked lines into lines for the header file.
+# The markers have already been removed.  Two things are done here:  removal
+# of backslashed newlines, and some fudging of comments.  The first is done
+# because -o needs to have prototypes on one line to strip them down.
+# Getting comments into the output is tricky; we turn C++-style // comments
+# into /* */ comments, after altering any existing */'s to avoid trouble.
+peel=' /\\$/N
+       /\\\n[  ]*/s///g
+       /\/\//s;\*/;* /;g
+       /\/\//s;//\(.*\);/*\1 */;'
+
+for a
+do
+       case "$a" in
+       -o)     # old (pre-function-prototype) compiler
+               # add code to comment out argument lists
+               peel="$peel
+                       "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1(/*\2*/);'
+               shift
+               ;;
+       -b)     # funny Berkeley __P macro
+               peel="$peel
+                       "'/^\([^#\/][^\/]*[a-zA-Z0-9_)]\)(\(.*\))/s;;\1 __P((\2));'
+               shift
+               ;;
+       -s)     # compiler doesn't like `static foo();'
+               # add code to get rid of the `static'
+               peel="$peel
+                       "'/^static[     ][^\/]*[a-zA-Z0-9_)](.*)/s;static.;;'
+               shift
+               ;;
+       -p)     # private declarations
+               egrep='^ ==([   ]|$)'
+               shift
+               ;;
+       -i)     # wrap in #ifndef, argument is name
+               ifndef="$2"
+               shift ; shift
+               ;;
+       *)      break
+               ;;
+       esac
+done
+
+if test " $ifndef" != " "
+then
+       echo "#ifndef $ifndef"
+       echo "#define   $ifndef /* never again */"
+fi
+echo "/* ========= begin header generated by $0 ========= */"
+echo '#ifdef __cplusplus'
+echo 'extern "C" {'
+echo '#endif'
+for f
+do
+       echo
+       echo "/* === $f === */"
+       egrep "$egrep" $f | sed 's/^ ==*[       ]//;s/^ ==*$//' | sed "$peel"
+       echo
+done
+echo '#ifdef __cplusplus'
+echo '}'
+echo '#endif'
+echo "/* ========= end header generated by $0 ========= */"
+if test " $ifndef" != " "
+then
+       echo "#endif"
+fi
+exit 0
diff --git a/regex-src/regcomp.c b/regex-src/regcomp.c
new file mode 100644 (file)
index 0000000..42c3b86
--- /dev/null
@@ -0,0 +1,1603 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "utils.h"
+#include "regex2.h"
+
+#include "cclass.h"
+#include "cname.h"
+
+/*
+ * parse structure, passed up and down to avoid global variables and
+ * other clumsinesses
+ */
+struct parse {
+       char *next;             /* next character in RE */
+       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) */
+       int ncsalloc;           /* number of csets allocated */
+       struct re_guts *g;
+#      define  NPAREN  10      /* we need to remember () 1-9 for back refs */
+       sopno pbegin[NPAREN];   /* -> ( ([0] unused) */
+       sopno pend[NPAREN];     /* -> ) ([0] unused) */
+};
+
+#include "regcomp.ih"
+
+static char nuls[10];          /* place to point scanner in event of error */
+
+/*
+ * macros for use with parse structure
+ * BEWARE:  these know that the parse structure is named `p' !!!
+ */
+#define        PEEK()  (*p->next)
+#define        PEEK2() (*(p->next+1))
+#define        MORE()  (p->next < p->end)
+#define        MORE2() (p->next+1 < p->end)
+#define        SEE(c)  (MORE() && PEEK() == (c))
+#define        SEETWO(a, b)    (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
+#define        EAT(c)  ((SEE(c)) ? (NEXT(), 1) : 0)
+#define        EATTWO(a, b)    ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
+#define        NEXT()  (p->next++)
+#define        NEXT2() (p->next += 2)
+#define        NEXTn(n)        (p->next += (n))
+#define        GETNEXT()       (*p->next++)
+#define        SETERROR(e)     seterr(p, (e))
+#define        REQUIRE(co, e)  ((co) || SETERROR(e))
+#define        MUSTSEE(c, e)   (REQUIRE(MORE() && PEEK() == (c), e))
+#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))
+
+#ifndef NDEBUG
+static int never = 0;          /* for use in asserts; shuts lint up */
+#else
+#define        never   0               /* some <assert.h>s have bugs too */
+#endif
+
+/*
+ - regcomp - interface for parser and compilation
+ = extern int regcomp(regex_t *, const char *, int);
+ = #define     REG_BASIC       0000
+ = #define     REG_EXTENDED    0001
+ = #define     REG_ICASE       0002
+ = #define     REG_NOSUB       0004
+ = #define     REG_NEWLINE     0010
+ = #define     REG_NOSPEC      0020
+ = #define     REG_PEND        0040
+ = #define     REG_DUMP        0200
+ */
+int                            /* 0 success, otherwise REG_something */
+regcomp(preg, pattern, cflags)
+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;
+#ifdef REDEBUG
+#      define  GOODFLAGS(f)    (f)
+#else
+#      define  GOODFLAGS(f)    ((f)&~REG_DUMP)
+#endif
+
+       cflags = GOODFLAGS(cflags);
+       if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
+               return(REG_INVARG);
+
+       if (cflags&REG_PEND) {
+               if (preg->re_endp < pattern)
+                       return(REG_INVARG);
+               len = preg->re_endp - pattern;
+       } else
+               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));
+       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->slen = 0;
+       if (p->strip == NULL) {
+               free((char *)g);
+               return(REG_ESPACE);
+       }
+
+       /* set things up */
+       p->g = g;
+       p->next = (char *)pattern;      /* convenience; we do not modify it */
+       p->end = p->next + len;
+       p->error = 0;
+       p->ncsalloc = 0;
+       for (i = 0; i < NPAREN; i++) {
+               p->pbegin[i] = 0;
+               p->pend[i] = 0;
+       }
+       g->csetsize = NC;
+       g->sets = NULL;
+       g->setbits = NULL;
+       g->ncsets = 0;
+       g->cflags = cflags;
+       g->iflags = 0;
+       g->nbol = 0;
+       g->neol = 0;
+       g->must = NULL;
+       g->mlen = 0;
+       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));
+       g->backrefs = 0;
+
+       /* do it */
+       EMIT(OEND, 0);
+       g->firststate = THERE();
+       if (cflags&REG_EXTENDED)
+               p_ere(p, OUT);
+       else if (cflags&REG_NOSPEC)
+               p_str(p);
+       else
+               p_bre(p, OUT, OUT);
+       EMIT(OEND, 0);
+       g->laststate = THERE();
+
+       /* tidy up loose ends and fill things in */
+       categorize(p, g);
+       stripsnug(p, g);
+       findmust(p, g);
+       g->nplus = pluscount(p, g);
+       g->magic = MAGIC2;
+       preg->re_nsub = g->nsub;
+       preg->re_g = g;
+       preg->re_magic = MAGIC1;
+#ifndef REDEBUG
+       /* not debugging, so can't rely on the assert() in regexec() */
+       if (g->iflags&BAD)
+               SETERROR(REG_ASSERT);
+#endif
+
+       /* win or lose, we're done */
+       if (p->error != 0)      /* lose */
+               regfree(preg);
+       return(p->error);
+}
+
+/*
+ - p_ere - ERE parser top level, concatenation and alternation
+ == static void p_ere(register struct parse *p, int stop);
+ */
+static void
+p_ere(p, stop)
+register struct parse *p;
+int stop;                      /* character this ERE should end at */
+{
+       register char c;
+       register sopno prevback;
+       register sopno prevfwd;
+       register sopno conc;
+       register 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 */
+
+               if (!EAT('|'))
+                       break;          /* NOTE BREAK OUT */
+
+               if (first) {
+                       INSERT(OCH_, conc);     /* offset is wrong */
+                       prevfwd = conc;
+                       prevback = conc;
+                       first = 0;
+               }
+               ASTERN(OOR1, prevback);
+               prevback = THERE();
+               AHEAD(prevfwd);                 /* fix previous offset */
+               prevfwd = HERE();
+               EMIT(OOR2, 0);                  /* offset is very wrong */
+       }
+
+       if (!first) {           /* tail-end fixups */
+               AHEAD(prevfwd);
+               ASTERN(O_CH, prevback);
+       }
+
+       assert(!MORE() || SEE(stop));
+}
+
+/*
+ - 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(p)
+register struct parse *p;
+{
+       register char c;
+       register sopno pos;
+       register int count;
+       register int count2;
+       register sopno subno;
+       int wascaret = 0;
+
+       assert(MORE());         /* caller should have ensured this */
+       c = GETNEXT();
+
+       pos = HERE();
+       switch (c) {
+       case '(':
+               REQUIRE(MORE(), REG_EPAREN);
+               p->g->nsub++;
+               subno = p->g->nsub;
+               if (subno < NPAREN)
+                       p->pbegin[subno] = HERE();
+               EMIT(OLPAREN, subno);
+               if (!SEE(')'))
+                       p_ere(p, ')');
+               if (subno < NPAREN) {
+                       p->pend[subno] = HERE();
+                       assert(p->pend[subno] != 0);
+               }
+               EMIT(ORPAREN, subno);
+               MUSTEAT(')', REG_EPAREN);
+               break;
+#ifndef POSIX_MISTAKE
+       case ')':               /* happens only if no current unmatched ( */
+               /*
+                * You may ask, why the ifndef?  Because I didn't notice
+                * this until slightly too late for 1003.2, and none of the
+                * other 1003.2 regular-expression reviewers noticed it at
+                * all.  So an unmatched ) is legal POSIX, at least until
+                * we can get it fixed.
+                */
+               SETERROR(REG_EPAREN);
+               break;
+#endif
+       case '^':
+               EMIT(OBOL, 0);
+               p->g->iflags |= USEBOL;
+               p->g->nbol++;
+               wascaret = 1;
+               break;
+       case '$':
+               EMIT(OEOL, 0);
+               p->g->iflags |= USEEOL;
+               p->g->neol++;
+               break;
+       case '|':
+               SETERROR(REG_EMPTY);
+               break;
+       case '*':
+       case '+':
+       case '?':
+               SETERROR(REG_BADRPT);
+               break;
+       case '.':
+               if (p->g->cflags&REG_NEWLINE)
+                       nonnewline(p);
+               else
+                       EMIT(OANY, 0);
+               break;
+       case '[':
+               p_bracket(p);
+               break;
+       case '\\':
+               REQUIRE(MORE(), REG_EESCAPE);
+               c = GETNEXT();
+               ordinary(p, c);
+               break;
+       case '{':               /* okay as ordinary except if digit follows */
+               REQUIRE(!MORE() || !isdigit(PEEK()), REG_BADRPT);
+               /* FALLTHROUGH */
+       default:
+               ordinary(p, c);
+               break;
+       }
+
+       if (!MORE())
+               return;
+       c = PEEK();
+       /* we call { a repetition if followed by a digit */
+       if (!( c == '*' || c == '+' || c == '?' ||
+                               (c == '{' && MORE2() && isdigit(PEEK2())) ))
+               return;         /* no repetition, we're done */
+       NEXT();
+
+       REQUIRE(!wascaret, REG_BADRPT);
+       switch (c) {
+       case '*':       /* implemented as +? */
+               /* this case does not require the (y|) trick, noKLUDGE */
+               INSERT(OPLUS_, pos);
+               ASTERN(O_PLUS, pos);
+               INSERT(OQUEST_, pos);
+               ASTERN(O_QUEST, pos);
+               break;
+       case '+':
+               INSERT(OPLUS_, pos);
+               ASTERN(O_PLUS, pos);
+               break;
+       case '?':
+               /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+               INSERT(OCH_, pos);              /* offset slightly wrong */
+               ASTERN(OOR1, pos);              /* this one's right */
+               AHEAD(pos);                     /* fix the OCH_ */
+               EMIT(OOR2, 0);                  /* offset very wrong... */
+               AHEAD(THERE());                 /* ...so fix it */
+               ASTERN(O_CH, THERETHERE());
+               break;
+       case '{':
+               count = p_count(p);
+               if (EAT(',')) {
+                       if (isdigit(PEEK())) {
+                               count2 = p_count(p);
+                               REQUIRE(count <= count2, REG_BADBR);
+                       } else          /* single number with comma */
+                               count2 = INFINITY;
+               } else          /* just a single number */
+                       count2 = count;
+               repeat(p, pos, count, count2);
+               if (!EAT('}')) {        /* error heuristics */
+                       while (MORE() && PEEK() != '}')
+                               NEXT();
+                       REQUIRE(MORE(), REG_EBRACE);
+                       SETERROR(REG_BADBR);
+               }
+               break;
+       }
+
+       if (!MORE())
+               return;
+       c = PEEK();
+       if (!( c == '*' || c == '+' || c == '?' ||
+                               (c == '{' && MORE2() && isdigit(PEEK2())) ) )
+               return;
+       SETERROR(REG_BADRPT);
+}
+
+/*
+ - p_str - string (no metacharacters) "parser"
+ == static void p_str(register struct parse *p);
+ */
+static void
+p_str(p)
+register struct parse *p;
+{
+       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);
+ * Giving end1 as OUT essentially eliminates the end1/end2 check.
+ *
+ * This implementation is a bit of a kludge, in that a trailing $ is first
+ * taken as an ordinary character and then revised to be an anchor.  The
+ * only undesirable side effect is that '$' gets included as a character
+ * category in such cases.  This is fairly harmless; not worth fixing.
+ * 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 */
+{
+       register sopno start = HERE();
+       register int first = 1;                 /* first subexpression? */
+       register int wasdollar = 0;
+
+       if (EAT('^')) {
+               EMIT(OBOL, 0);
+               p->g->iflags |= USEBOL;
+               p->g->nbol++;
+       }
+       while (MORE() && !SEETWO(end1, end2)) {
+               wasdollar = p_simp_re(p, first);
+               first = 0;
+       }
+       if (wasdollar) {        /* oops, that was a trailing anchor */
+               DROP(1);
+               EMIT(OEOL, 0);
+               p->g->iflags |= USEEOL;
+               p->g->neol++;
+       }
+
+       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                     /* was the simple RE an unbackslashed $? */
+p_simp_re(p, starordinary)
+register 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;
+#      define  BACKSL  (1<<CHAR_BIT)
+
+       pos = HERE();           /* repetion op, if any, covers from here */
+
+       assert(MORE());         /* caller should have ensured this */
+       c = GETNEXT();
+       if (c == '\\') {
+               REQUIRE(MORE(), REG_EESCAPE);
+               c = BACKSL | (unsigned char)GETNEXT();
+       }
+       switch (c) {
+       case '.':
+               if (p->g->cflags&REG_NEWLINE)
+                       nonnewline(p);
+               else
+                       EMIT(OANY, 0);
+               break;
+       case '[':
+               p_bracket(p);
+               break;
+       case BACKSL|'{':
+               SETERROR(REG_BADRPT);
+               break;
+       case BACKSL|'(':
+               p->g->nsub++;
+               subno = p->g->nsub;
+               if (subno < NPAREN)
+                       p->pbegin[subno] = HERE();
+               EMIT(OLPAREN, subno);
+               /* the MORE here is an error heuristic */
+               if (MORE() && !SEETWO('\\', ')'))
+                       p_bre(p, '\\', ')');
+               if (subno < NPAREN) {
+                       p->pend[subno] = HERE();
+                       assert(p->pend[subno] != 0);
+               }
+               EMIT(ORPAREN, subno);
+               REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
+               break;
+       case BACKSL|')':        /* should not get here -- must be user */
+       case BACKSL|'}':
+               SETERROR(REG_EPAREN);
+               break;
+       case BACKSL|'1':
+       case BACKSL|'2':
+       case BACKSL|'3':
+       case BACKSL|'4':
+       case BACKSL|'5':
+       case BACKSL|'6':
+       case BACKSL|'7':
+       case BACKSL|'8':
+       case BACKSL|'9':
+               i = (c&~BACKSL) - '0';
+               assert(i < NPAREN);
+               if (p->pend[i] != 0) {
+                       assert(i <= 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]);
+                       EMIT(O_BACK, i);
+               } else
+                       SETERROR(REG_ESUBREG);
+               p->g->backrefs = 1;
+               break;
+       case '*':
+               REQUIRE(starordinary, REG_BADRPT);
+               /* FALLTHROUGH */
+       default:
+               ordinary(p, c &~ BACKSL);
+               break;
+       }
+
+       if (EAT('*')) {         /* implemented as +? */
+               /* this case does not require the (y|) trick, noKLUDGE */
+               INSERT(OPLUS_, pos);
+               ASTERN(O_PLUS, pos);
+               INSERT(OQUEST_, pos);
+               ASTERN(O_QUEST, pos);
+       } else if (EATTWO('\\', '{')) {
+               count = p_count(p);
+               if (EAT(',')) {
+                       if (MORE() && isdigit(PEEK())) {
+                               count2 = p_count(p);
+                               REQUIRE(count <= count2, REG_BADBR);
+                       } else          /* single number with comma */
+                               count2 = INFINITY;
+               } else          /* just a single number */
+                       count2 = count;
+               repeat(p, pos, count, count2);
+               if (!EATTWO('\\', '}')) {       /* error heuristics */
+                       while (MORE() && !SEETWO('\\', '}'))
+                               NEXT();
+                       REQUIRE(MORE(), REG_EBRACE);
+                       SETERROR(REG_BADBR);
+               }
+       } else if (c == (unsigned char)'$')     /* $ (but not \$) ends it */
+               return(1);
+
+       return(0);
+}
+
+/*
+ - p_count - parse a repetition count
+ == static int p_count(register struct parse *p);
+ */
+static int                     /* the value */
+p_count(p)
+register struct parse *p;
+{
+       register int count = 0;
+       register int ndigits = 0;
+
+       while (MORE() && isdigit(PEEK()) && count <= DUPMAX) {
+               count = count*10 + (GETNEXT() - '0');
+               ndigits++;
+       }
+
+       REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
+       return(count);
+}
+
+/*
+ - p_bracket - parse a bracketed character list
+ == static void p_bracket(register 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;
+{
+       register cset *cs = allocset(p);
+       register int invert = 0;
+
+       /* Dept of Truly Sickening Special-Case Kludges */
+       if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
+               EMIT(OBOW, 0);
+               NEXTn(6);
+               return;
+       }
+       if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
+               EMIT(OEOW, 0);
+               NEXTn(6);
+               return;
+       }
+
+       if (EAT('^'))
+               invert++;       /* make note to invert set at end */
+       if (EAT(']'))
+               CHadd(cs, ']');
+       else if (EAT('-'))
+               CHadd(cs, '-');
+       while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
+               p_b_term(p, cs);
+       if (EAT('-'))
+               CHadd(cs, '-');
+       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;
+
+               for (i = p->g->csetsize - 1; i >= 0; i--)
+                       if (CHIN(cs, i) && isalpha(i)) {
+                               ci = othercase(i);
+                               if (ci != i)
+                                       CHadd(cs, ci);
+                       }
+               if (cs->multis != NULL)
+                       mccase(p, cs);
+       }
+       if (invert) {
+               register int i;
+
+               for (i = p->g->csetsize - 1; i >= 0; i--)
+                       if (CHIN(cs, i))
+                               CHsub(cs, i);
+                       else
+                               CHadd(cs, i);
+               if (p->g->cflags&REG_NEWLINE)
+                       CHsub(cs, '\n');
+               if (cs->multis != NULL)
+                       mcinvert(p, cs);
+       }
+
+       assert(cs->multis == NULL);             /* xxx */
+
+       if (nch(p, cs) == 1) {          /* optimize singleton sets */
+               ordinary(p, firstch(p, cs));
+               freeset(p, cs);
+       } else
+               EMIT(OANYOF, freezeset(p, cs));
+}
+
+/*
+ - 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(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+       register char c;
+       register char start, finish;
+       register int i;
+
+       /* classify what we've got */
+       switch ((MORE()) ? PEEK() : '\0') {
+       case '[':
+               c = (MORE2()) ? PEEK2() : '\0';
+               break;
+       case '-':
+               SETERROR(REG_ERANGE);
+               return;                 /* NOTE RETURN */
+               break;
+       default:
+               c = '\0';
+               break;
+       }
+
+       switch (c) {
+       case ':':               /* character class */
+               NEXT2();
+               REQUIRE(MORE(), REG_EBRACK);
+               c = PEEK();
+               REQUIRE(c != '-' && c != ']', REG_ECTYPE);
+               p_b_cclass(p, cs);
+               REQUIRE(MORE(), REG_EBRACK);
+               REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
+               break;
+       case '=':               /* equivalence class */
+               NEXT2();
+               REQUIRE(MORE(), REG_EBRACK);
+               c = PEEK();
+               REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
+               p_b_eclass(p, cs);
+               REQUIRE(MORE(), REG_EBRACK);
+               REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
+               break;
+       default:                /* symbol, ordinary character, or range */
+/* xxx revision needed for multichar stuff */
+               start = p_b_symbol(p);
+               if (SEE('-') && MORE2() && PEEK2() != ']') {
+                       /* range */
+                       NEXT();
+                       if (EAT('-'))
+                               finish = '-';
+                       else
+                               finish = p_b_symbol(p);
+               } else
+                       finish = start;
+/* xxx what about signed chars here... */
+               REQUIRE(start <= finish, REG_ERANGE);
+               for (i = start; i <= finish; i++)
+                       CHadd(cs, i);
+               break;
+       }
+}
+
+/*
+ - 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(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+       register char *sp = p->next;
+       register struct cclass *cp;
+       register size_t len;
+       register char *u;
+       register char c;
+
+       while (MORE() && isalpha(PEEK()))
+               NEXT();
+       len = p->next - sp;
+       for (cp = cclasses; cp->name != NULL; cp++)
+               if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
+                       break;
+       if (cp->name == NULL) {
+               /* oops, didn't find it */
+               SETERROR(REG_ECTYPE);
+               return;
+       }
+
+       u = cp->chars;
+       while ((c = *u++) != '\0')
+               CHadd(cs, c);
+       for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
+               MCadd(p, cs, u);
+}
+
+/*
+ - p_b_eclass - parse an equivalence-class name and deal with it
+ == static void p_b_eclass(register 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;
+{
+       register char c;
+
+       c = 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                    /* value of symbol */
+p_b_symbol(p)
+register struct parse *p;
+{
+       register char value;
+
+       REQUIRE(MORE(), REG_EBRACK);
+       if (!EATTWO('[', '.'))
+               return(GETNEXT());
+
+       /* collating symbol */
+       value = p_b_coll_elem(p, '.');
+       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                    /* value of collating element */
+p_b_coll_elem(p, endc)
+register struct parse *p;
+int endc;                      /* name ended by endc,']' */
+{
+       register char *sp = p->next;
+       register struct cname *cp;
+       register int len;
+
+       while (MORE() && !SEETWO(endc, ']'))
+               NEXT();
+       if (!MORE()) {
+               SETERROR(REG_EBRACK);
+               return(0);
+       }
+       len = 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);
+}
+
+/*
+ - othercase - return the case counterpart of an alphabetic
+ == static char othercase(int ch);
+ */
+static char                    /* if no counterpart, return ch */
+othercase(ch)
+int ch;
+{
+       assert(isalpha(ch));
+       if (isupper(ch))
+               return(tolower(ch));
+       else if (islower(ch))
+               return(toupper(ch));
+       else                    /* peculiar, but could happen */
+               return(ch);
+}
+
+/*
+ - bothcases - emit a dualcase version of a two-case character
+ == static void bothcases(register struct parse *p, int ch);
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+bothcases(p, ch)
+register struct parse *p;
+int ch;
+{
+       register char *oldnext = p->next;
+       register char *oldend = p->end;
+       char bracket[3];
+
+       assert(othercase(ch) != ch);    /* p_bracket() would recurse */
+       p->next = bracket;
+       p->end = bracket+2;
+       bracket[0] = ch;
+       bracket[1] = ']';
+       bracket[2] = '\0';
+       p_bracket(p);
+       assert(p->next == bracket+2);
+       p->next = oldnext;
+       p->end = oldend;
+}
+
+/*
+ - ordinary - emit an ordinary character
+ == static void ordinary(register struct parse *p, register int ch);
+ */
+static void
+ordinary(p, ch)
+register struct parse *p;
+register int ch;
+{
+       register 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++;
+       }
+}
+
+/*
+ - nonnewline - emit REG_NEWLINE version of OANY
+ == static void nonnewline(register struct parse *p);
+ *
+ * Boy, is this implementation ever a kludge...
+ */
+static void
+nonnewline(p)
+register struct parse *p;
+{
+       register char *oldnext = p->next;
+       register char *oldend = p->end;
+       char bracket[4];
+
+       p->next = bracket;
+       p->end = bracket+3;
+       bracket[0] = '^';
+       bracket[1] = '\n';
+       bracket[2] = ']';
+       bracket[3] = '\0';
+       p_bracket(p);
+       assert(p->next == bracket+3);
+       p->next = oldnext;
+       p->end = oldend;
+}
+
+/*
+ - 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(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) */
+{
+       register 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;
+
+       if (p->error != 0)      /* head off possible runaway recursion */
+               return;
+
+       assert(from <= to);
+
+       switch (REP(MAP(from), MAP(to))) {
+       case REP(0, 0):                 /* must be user doing this */
+               DROP(finish-start);     /* drop the operand */
+               break;
+       case REP(0, 1):                 /* as x{1,1}? */
+       case REP(0, N):                 /* as x{1,n}? */
+       case REP(0, INF):               /* as x{1,}? */
+               /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+               INSERT(OCH_, start);            /* offset is wrong... */
+               repeat(p, start+1, 1, to);
+               ASTERN(OOR1, start);
+               AHEAD(start);                   /* ... fix it */
+               EMIT(OOR2, 0);
+               AHEAD(THERE());
+               ASTERN(O_CH, THERETHERE());
+               break;
+       case REP(1, 1):                 /* trivial case */
+               /* done */
+               break;
+       case REP(1, N):                 /* as x?x{1,n-1} */
+               /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
+               INSERT(OCH_, start);
+               ASTERN(OOR1, start);
+               AHEAD(start);
+               EMIT(OOR2, 0);                  /* offset very wrong... */
+               AHEAD(THERE());                 /* ...so fix it */
+               ASTERN(O_CH, THERETHERE());
+               copy = dupl(p, start+1, finish+1);
+               assert(copy == finish+4);
+               repeat(p, copy, 1, to-1);
+               break;
+       case REP(1, INF):               /* as x+ */
+               INSERT(OPLUS_, start);
+               ASTERN(O_PLUS, start);
+               break;
+       case REP(N, N):                 /* as xx{m-1,n-1} */
+               copy = dupl(p, start, finish);
+               repeat(p, copy, from-1, to-1);
+               break;
+       case REP(N, INF):               /* as xx{n-1,INF} */
+               copy = dupl(p, start, finish);
+               repeat(p, copy, from-1, to);
+               break;
+       default:                        /* "can't happen" */
+               SETERROR(REG_ASSERT);   /* just in case */
+               break;
+       }
+}
+
+/*
+ - seterr - set an error condition
+ == static int seterr(register struct parse *p, int e);
+ */
+static int                     /* useless but makes type checking happy */
+seterr(p, e)
+register struct parse *p;
+int e;
+{
+       if (p->error == 0)      /* keep earliest error condition */
+               p->error = e;
+       p->next = nuls;         /* try to bring things to a halt */
+       p->end = nuls;
+       return(0);              /* make the return value well-defined */
+}
+
+/*
+ - allocset - allocate a set of characters for []
+ == static cset *allocset(register struct parse *p);
+ */
+static cset *
+allocset(p)
+register 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;
+
+       if (no >= p->ncsalloc) {        /* need another column of space */
+               p->ncsalloc += CHAR_BIT;
+               nc = p->ncsalloc;
+               assert(nc % CHAR_BIT == 0);
+               nbytes = nc / CHAR_BIT * css;
+               if (p->g->sets == NULL)
+                       p->g->sets = (cset *)malloc(nc * sizeof(cset));
+               else
+                       p->g->sets = (cset *)realloc((char *)p->g->sets,
+                                                       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 != NULL && p->g->setbits != NULL)
+                       (void) memset((char *)p->g->setbits + (nbytes - css),
+                                                               0, css);
+               else {
+                       no = 0;
+                       SETERROR(REG_ESPACE);
+                       /* caller's responsibility not to do set ops */
+               }
+       }
+
+       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->hash = 0;
+       cs->smultis = 0;
+       cs->multis = NULL;
+
+       return(cs);
+}
+
+/*
+ - freeset - free a now-unused set
+ == static void freeset(register struct parse *p, register cset *cs);
+ */
+static void
+freeset(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+       register int i;
+       register cset *top = &p->g->sets[p->g->ncsets];
+       register size_t css = (size_t)p->g->csetsize;
+
+       for (i = 0; i < css; i++)
+               CHsub(cs, i);
+       if (cs == top-1)        /* recover only the easy case */
+               p->g->ncsets--;
+}
+
+/*
+ - freezeset - final processing on a set of characters
+ == static int freezeset(register 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
+ * big if REG_ICASE is being used.  REG_ICASE, by the way, is why the hash
+ * is done using addition rather than xor -- all ASCII [aA] sets xor to
+ * the same value!
+ */
+static int                     /* set number */
+freezeset(p, cs)
+register struct parse *p;
+register 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;
+
+       /* look for an earlier one which is the same */
+       for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
+               if (cs2->hash == h && cs2 != cs) {
+                       /* maybe */
+                       for (i = 0; i < css; i++)
+                               if (!!CHIN(cs2, i) != !!CHIN(cs, i))
+                                       break;          /* no */
+                       if (i == css)
+                               break;                  /* yes */
+               }
+
+       if (cs2 < top) {        /* found one */
+               freeset(p, cs);
+               cs = cs2;
+       }
+
+       return((int)(cs - p->g->sets));
+}
+
+/*
+ - 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                     /* character; there is no "none" value */
+firstch(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+       register int i;
+       register size_t css = (size_t)p->g->csetsize;
+
+       for (i = 0; i < css; i++)
+               if (CHIN(cs, i))
+                       return((char)i);
+       assert(never);
+       return(0);              /* arbitrary */
+}
+
+/*
+ - nch - number of characters in a set
+ == static int nch(register struct parse *p, register cset *cs);
+ */
+static int
+nch(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+       register int i;
+       register size_t css = (size_t)p->g->csetsize;
+       register int n = 0;
+
+       for (i = 0; i < css; i++)
+               if (CHIN(cs, i))
+                       n++;
+       return(n);
+}
+
+/*
+ - mcadd - add a collating element to a cset
+ == static void mcadd(register struct parse *p, register cset *cs, \
+ ==    register char *cp);
+ */
+static void
+mcadd(p, cs, cp)
+register struct parse *p;
+register cset *cs;
+register char *cp;
+{
+       register 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);
+       if (cs->multis == NULL) {
+               SETERROR(REG_ESPACE);
+               return;
+       }
+
+       (void) strcpy(cs->multis + oldend - 1, cp);
+       cs->multis[cs->smultis - 1] = '\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);
+}
+
+/*
+ - mcinvert - invert the list of collating elements in a cset
+ == static void mcinvert(register 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;
+{
+       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);
+ *
+ * This would have to know the set of possibilities.  Implementation
+ * is deferred.
+ */
+static void
+mccase(p, cs)
+register struct parse *p;
+register cset *cs;
+{
+       assert(cs->multis == NULL);     /* xxx */
+}
+
+/*
+ - isinsets - is this character in any sets?
+ == static int isinsets(register struct re_guts *g, int c);
+ */
+static int                     /* predicate */
+isinsets(g, c)
+register 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;
+
+       for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+               if (col[uc] != 0)
+                       return(1);
+       return(0);
+}
+
+/*
+ - samesets - are these two characters in exactly the same sets?
+ == static int samesets(register struct re_guts *g, int c1, int c2);
+ */
+static int                     /* predicate */
+samesets(g, c1, c2)
+register 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;
+
+       for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
+               if (col[uc1] != col[uc2])
+                       return(0);
+       return(1);
+}
+
+/*
+ - categorize - sort out character categories
+ == static void categorize(struct parse *p, register struct re_guts *g);
+ */
+static void
+categorize(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+       register cat_t *cats = g->categories;
+       register int c;
+       register int c2;
+       register cat_t cat;
+
+       /* avoid making error situations worse */
+       if (p->error != 0)
+               return;
+
+       for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+               if (cats[c] == 0 && isinsets(g, c)) {
+                       cat = g->ncategories++;
+                       cats[c] = cat;
+                       for (c2 = c+1; c2 <= CHAR_MAX; c2++)
+                               if (cats[c2] == 0 && samesets(g, c, c2))
+                                       cats[c2] = cat;
+               }
+}
+
+/*
+ - dupl - emit a duplicate of a bunch of sops
+ == static sopno dupl(register 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 */
+{
+       register sopno ret = HERE();
+       register sopno len = 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);
+       (void) memcpy((char *)(p->strip + p->slen),
+               (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);
+ *
+ * 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;
+{
+       /* avoid making error situations worse */
+       if (p->error != 0)
+               return;
+
+       /* deal with oversize operands ("can't happen", more or less) */
+       assert(opnd < 1<<OPSHIFT);
+
+       /* deal with undersized strip */
+       if (p->slen >= p->ssize)
+               enlarge(p, (p->ssize+1) / 2 * 3);       /* +50% */
+       assert(p->slen < p->ssize);
+
+       /* finally, it's all reduced to the easy case */
+       p->strip[p->slen++] = SOP(op, 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(p, op, opnd, pos)
+register struct parse *p;
+sop op;
+size_t opnd;
+sopno pos;
+{
+       register sopno sn;
+       register sop s;
+       register int i;
+
+       /* avoid making error situations worse */
+       if (p->error != 0)
+               return;
+
+       sn = HERE();
+       EMIT(op, opnd);         /* do checks, ensure space */
+       assert(HERE() == sn+1);
+       s = p->strip[sn];
+
+       /* adjust paren pointers */
+       assert(pos > 0);
+       for (i = 1; i < NPAREN; i++) {
+               if (p->pbegin[i] >= pos) {
+                       p->pbegin[i]++;
+               }
+               if (p->pend[i] >= pos) {
+                       p->pend[i]++;
+               }
+       }
+
+       memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
+                                               (HERE()-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(p, pos, value)
+register struct parse *p;
+register sopno pos;
+sop value;
+{
+       /* avoid making error situations worse */
+       if (p->error != 0)
+               return;
+
+       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(p, size)
+register struct parse *p;
+register sopno size;
+{
+       register sop *sp;
+
+       if (p->ssize >= size)
+               return;
+
+       sp = (sop *)realloc(p->strip, size*sizeof(sop));
+       if (sp == NULL) {
+               SETERROR(REG_ESPACE);
+               return;
+       }
+       p->strip = sp;
+       p->ssize = size;
+}
+
+/*
+ - stripsnug - compact the strip
+ == static void stripsnug(register struct parse *p, register struct re_guts *g);
+ */
+static void
+stripsnug(p, g)
+register struct parse *p;
+register struct re_guts *g;
+{
+       g->nstates = p->slen;
+       g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
+       if (g->strip == NULL) {
+               SETERROR(REG_ESPACE);
+               g->strip = p->strip;
+       }
+}
+
+/*
+ - findmust - fill in must and mlen with longest mandatory literal string
+ == static void findmust(register 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
+ * of the interesting cases.
+ *
+ * Note that must and mlen got initialized during setup.
+ */
+static void
+findmust(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+       register sop *scan;
+       sop *start;
+       register sop *newstart;
+       register sopno newlen;
+       register sop s;
+       register char *cp;
+       register sopno i;
+
+       /* avoid making error situations worse */
+       if (p->error != 0)
+               return;
+
+       /* find the longest OCHAR sequence in strip */
+       newlen = 0;
+       scan = g->strip + 1;
+       do {
+               s = *scan++;
+               switch (OP(s)) {
+               case OCHAR:             /* sequence member */
+                       if (newlen == 0)                /* new sequence */
+                               newstart = scan - 1;
+                       newlen++;
+                       break;
+               case OPLUS_:            /* things that don't break one */
+               case OLPAREN:
+               case ORPAREN:
+                       break;
+               case OQUEST_:           /* things that must be skipped */
+               case OCH_:
+                       scan--;
+                       do {
+                               scan += OPND(s);
+                               s = *scan;
+                               /* assert() interferes w debug printouts */
+                               if (OP(s) != O_QUEST && OP(s) != O_CH &&
+                                                       OP(s) != OOR2) {
+                                       g->iflags |= BAD;
+                                       return;
+                               }
+                       } while (OP(s) != O_QUEST && OP(s) != O_CH);
+                       /* fallthrough */
+               default:                /* things that break a sequence */
+                       if (newlen > g->mlen) {         /* ends one */
+                               start = newstart;
+                               g->mlen = newlen;
+                       }
+                       newlen = 0;
+                       break;
+               }
+       } while (OP(s) != OEND);
+
+       if (g->mlen == 0)               /* there isn't one */
+               return;
+
+       /* turn it into a character string */
+       g->must = malloc((size_t)g->mlen + 1);
+       if (g->must == NULL) {          /* argh; just forget it */
+               g->mlen = 0;
+               return;
+       }
+       cp = g->must;
+       scan = start;
+       for (i = g->mlen; i > 0; i--) {
+               while (OP(s = *scan++) != OCHAR)
+                       continue;
+               assert(cp < g->must + g->mlen);
+               *cp++ = (char)OPND(s);
+       }
+       assert(cp == g->must + g->mlen);
+       *cp++ = '\0';           /* just on general principles */
+}
+
+/*
+ - pluscount - count + nesting
+ == static sopno pluscount(register struct parse *p, register struct re_guts *g);
+ */
+static sopno                   /* nesting depth */
+pluscount(p, g)
+struct parse *p;
+register struct re_guts *g;
+{
+       register sop *scan;
+       register sop s;
+       register sopno plusnest = 0;
+       register sopno maxnest = 0;
+
+       if (p->error != 0)
+               return(0);      /* there may not be an OEND */
+
+       scan = g->strip + 1;
+       do {
+               s = *scan++;
+               switch (OP(s)) {
+               case OPLUS_:
+                       plusnest++;
+                       break;
+               case O_PLUS:
+                       if (plusnest > maxnest)
+                               maxnest = plusnest;
+                       plusnest--;
+                       break;
+               }
+       } while (OP(s) != OEND);
+       if (plusnest != 0)
+               g->iflags |= BAD;
+       return(maxnest);
+}
diff --git a/regex-src/regerror.c b/regex-src/regerror.c
new file mode 100644 (file)
index 0000000..ee27c6a
--- /dev/null
@@ -0,0 +1,130 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "utils.h"
+#include "regerror.ih"
+
+/*
+ = #define     REG_OKAY         0
+ = #define     REG_NOMATCH      1
+ = #define     REG_BADPAT       2
+ = #define     REG_ECOLLATE     3
+ = #define     REG_ECTYPE       4
+ = #define     REG_EESCAPE      5
+ = #define     REG_ESUBREG      6
+ = #define     REG_EBRACK       7
+ = #define     REG_EPAREN       8
+ = #define     REG_EBRACE       9
+ = #define     REG_BADBR       10
+ = #define     REG_ERANGE      11
+ = #define     REG_ESPACE      12
+ = #define     REG_BADRPT      13
+ = #define     REG_EMPTY       14
+ = #define     REG_ASSERT      15
+ = #define     REG_INVARG      16
+ = #define     REG_ATOI        255     // convert name to number (!)
+ = #define     REG_ITOA        0400    // convert number to name (!)
+ */
+static struct rerr {
+       int code;
+       char *name;
+       char *explain;
+} rerrs[] = {
+       REG_OKAY,       "REG_OKAY",     "no errors detected",
+       REG_NOMATCH,    "REG_NOMATCH",  "regexec() failed to match",
+       REG_BADPAT,     "REG_BADPAT",   "invalid regular expression",
+       REG_ECOLLATE,   "REG_ECOLLATE", "invalid collating element",
+       REG_ECTYPE,     "REG_ECTYPE",   "invalid character class",
+       REG_EESCAPE,    "REG_EESCAPE",  "trailing backslash (\\)",
+       REG_ESUBREG,    "REG_ESUBREG",  "invalid backreference number",
+       REG_EBRACK,     "REG_EBRACK",   "brackets ([ ]) not balanced",
+       REG_EPAREN,     "REG_EPAREN",   "parentheses not balanced",
+       REG_EBRACE,     "REG_EBRACE",   "braces not balanced",
+       REG_BADBR,      "REG_BADBR",    "invalid repetition count(s)",
+       REG_ERANGE,     "REG_ERANGE",   "invalid character range",
+       REG_ESPACE,     "REG_ESPACE",   "out of memory",
+       REG_BADRPT,     "REG_BADRPT",   "repetition-operator operand invalid",
+       REG_EMPTY,      "REG_EMPTY",    "empty (sub)expression",
+       REG_ASSERT,     "REG_ASSERT",   "\"can't happen\" -- you found a bug",
+       REG_INVARG,     "REG_INVARG",   "invalid argument to regex routine",
+       -1,             "",             "*** unknown regexp error code ***",
+};
+
+/*
+ - regerror - the interface to error numbers
+ = extern size_t regerror(int, const regex_t *, char *, size_t);
+ */
+/* ARGSUSED */
+size_t
+regerror(errcode, preg, errbuf, errbuf_size)
+int errcode;
+const regex_t *preg;
+char *errbuf;
+size_t errbuf_size;
+{
+       register struct rerr *r;
+       register size_t len;
+       register int target = errcode &~ REG_ITOA;
+       register char *s;
+       char convbuf[50];
+
+       if (errcode == REG_ATOI)
+               s = regatoi(preg, convbuf, sizeof(convbuf));
+       else {
+               for (r = rerrs; r->code >= 0; r++)
+                       if (r->code == target)
+                               break;
+
+               if (errcode&REG_ITOA) {
+                       if (r->code >= 0) {
+                               strncpy(convbuf, r->name, sizeof(convbuf)-1);
+                               convbuf[sizeof(convbuf)-1] = '\0';
+                       } else {
+                               ap_snprintf(convbuf, sizeof(convbuf),
+                                           "REG_0x%x", target);
+                       }
+                       assert(strlen(convbuf) < sizeof(convbuf));
+                       s = convbuf;
+               } else
+                       s = r->explain;
+       }
+
+       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';
+               }
+       }
+
+       return(len);
+}
+
+/*
+ - regatoi - internal routine to implement REG_ATOI
+ == static char *regatoi(const regex_t *preg, char *localbuf, int buflen);
+ */
+static char *
+regatoi(preg, localbuf, buflen)
+const regex_t *preg;
+char *localbuf;
+int buflen;
+{
+       register struct rerr *r;
+
+       for (r = rerrs; r->code >= 0; r++)
+               if (strcmp(r->name, preg->re_endp) == 0)
+                       break;
+       if (r->code < 0)
+               return("0");
+
+       ap_snprintf(localbuf, buflen, "%d", r->code);
+       return(localbuf);
+}
diff --git a/regex-src/regex.3 b/regex-src/regex.3
new file mode 100644 (file)
index 0000000..bc74709
--- /dev/null
@@ -0,0 +1,509 @@
+.TH REGEX 3 "25 Sept 1997"
+.BY "Henry Spencer"
+.de ZR
+.\" one other place knows this name:  the SEE ALSO section
+.IR regex (7) \\$1
+..
+.SH NAME
+regcomp, regexec, regerror, regfree \- regular-expression library
+.SH SYNOPSIS
+.ft B
+.\".na
+#include <sys/types.h>
+.br
+#include <regex.h>
+.HP 10
+int regcomp(regex_t\ *preg, const\ char\ *pattern, int\ cflags);
+.HP
+int\ regexec(const\ regex_t\ *preg, const\ char\ *string,
+size_t\ nmatch, regmatch_t\ pmatch[], int\ eflags);
+.HP
+size_t\ regerror(int\ errcode, const\ regex_t\ *preg,
+char\ *errbuf, size_t\ errbuf_size);
+.HP
+void\ regfree(regex_t\ *preg);
+.\".ad
+.ft
+.SH DESCRIPTION
+These routines implement POSIX 1003.2 regular expressions (``RE''s);
+see
+.ZR .
+.I Regcomp
+compiles an RE written as a string into an internal form,
+.I regexec
+matches that internal form against a string and reports results,
+.I regerror
+transforms error codes from either into human-readable messages,
+and
+.I regfree
+frees any dynamically-allocated storage used by the internal form
+of an RE.
+.PP
+The header
+.I <regex.h>
+declares two structure types,
+.I regex_t
+and
+.IR regmatch_t ,
+the former for compiled internal forms and the latter for match reporting.
+It also declares the four functions,
+a type
+.IR regoff_t ,
+and a number of constants with names starting with ``REG_''.
+.PP
+.I Regcomp
+compiles the regular expression contained in the
+.I pattern
+string,
+subject to the flags in
+.IR cflags ,
+and places the results in the
+.I regex_t
+structure pointed to by
+.IR preg .
+.I Cflags
+is the bitwise OR of zero or more of the following flags:
+.IP REG_EXTENDED \w'REG_EXTENDED'u+2n
+Compile modern (``extended'') REs,
+rather than the obsolete (``basic'') REs that
+are the default.
+.IP REG_BASIC
+This is a synonym for 0,
+provided as a counterpart to REG_EXTENDED to improve readability.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.IP REG_NOSPEC
+Compile with recognition of all special characters turned off.
+All characters are thus considered ordinary,
+so the ``RE'' is a literal string.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+REG_EXTENDED and REG_NOSPEC may not be used
+in the same call to
+.IR regcomp .
+.IP REG_ICASE
+Compile for matching that ignores upper/lower case distinctions.
+See
+.ZR .
+.IP REG_NOSUB
+Compile for matching that need only report success or failure,
+not what was matched.
+.IP REG_NEWLINE
+Compile for newline-sensitive matching.
+By default, newline is a completely ordinary character with no special
+meaning in either REs or strings.
+With this flag,
+`[^' bracket expressions and `.' never match newline,
+a `^' anchor matches the null string after any newline in the string
+in addition to its normal function,
+and the `$' anchor matches the null string before any newline in the
+string in addition to its normal function.
+.IP REG_PEND
+The regular expression ends,
+not at the first NUL,
+but just before the character pointed to by the
+.I re_endp
+member of the structure pointed to by
+.IR preg .
+The
+.I re_endp
+member is of type
+.IR const\ char\ * .
+This flag permits inclusion of NULs in the RE;
+they are considered ordinary characters.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.PP
+When successful,
+.I regcomp
+returns 0 and fills in the structure pointed to by
+.IR preg .
+One member of that structure
+(other than
+.IR re_endp )
+is publicized:
+.IR re_nsub ,
+of type
+.IR size_t ,
+contains the number of parenthesized subexpressions within the RE
+(except that the value of this member is undefined if the
+REG_NOSUB flag was used).
+If
+.I regcomp
+fails, it returns a non-zero error code;
+see DIAGNOSTICS.
+.PP
+.I Regexec
+matches the compiled RE pointed to by
+.I preg
+against the
+.IR string ,
+subject to the flags in
+.IR eflags ,
+and reports results using
+.IR nmatch ,
+.IR pmatch ,
+and the returned value.
+The RE must have been compiled by a previous invocation of
+.IR regcomp .
+The compiled form is not altered during execution of
+.IR regexec ,
+so a single compiled RE can be used simultaneously by multiple threads.
+.PP
+By default,
+the NUL-terminated string pointed to by
+.I string
+is considered to be the text of an entire line,
+with the NUL indicating the end of the line.
+(That is,
+any other end-of-line marker is considered to have been removed
+and replaced by the NUL.)
+The
+.I eflags
+argument is the bitwise OR of zero or more of the following flags:
+.IP REG_NOTBOL \w'REG_STARTEND'u+2n
+The first character of
+the string
+is not the beginning of a line, so the `^' anchor should not match before it.
+This does not affect the behavior of newlines under REG_NEWLINE.
+.IP REG_NOTEOL
+The NUL terminating
+the string
+does not end a line, so the `$' anchor should not match before it.
+This does not affect the behavior of newlines under REG_NEWLINE.
+.IP REG_STARTEND
+The string is considered to start at
+\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_so\fR
+and to have a terminating NUL located at
+\fIstring\fR\ + \fIpmatch\fR[0].\fIrm_eo\fR
+(there need not actually be a NUL at that location),
+regardless of the value of
+.IR nmatch .
+See below for the definition of
+.IR pmatch
+and
+.IR nmatch .
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+Note that a non-zero \fIrm_so\fR does not imply REG_NOTBOL;
+REG_STARTEND affects only the location of the string,
+not how it is matched.
+.PP
+See
+.ZR
+for a discussion of what is matched in situations where an RE or a
+portion thereof could match any of several substrings of
+.IR string .
+.PP
+Normally,
+.I regexec
+returns 0 for success and the non-zero code REG_NOMATCH for failure.
+Other non-zero error codes may be returned in exceptional situations;
+see DIAGNOSTICS.
+.PP
+If REG_NOSUB was specified in the compilation of the RE,
+or if
+.I nmatch
+is 0,
+.I regexec
+ignores the
+.I pmatch
+argument (but see below for the case where REG_STARTEND is specified).
+Otherwise,
+.I pmatch
+points to an array of
+.I nmatch
+structures of type
+.IR regmatch_t .
+Such a structure has at least the members
+.I rm_so
+and
+.IR rm_eo ,
+both of type
+.I regoff_t
+(a signed arithmetic type at least as large as an
+.I off_t
+and a
+.IR ssize_t ),
+containing respectively the offset of the first character of a substring
+and the offset of the first character after the end of the substring.
+Offsets are measured from the beginning of the
+.I string
+argument given to
+.IR regexec .
+An empty substring is denoted by equal offsets,
+both indicating the character following the empty substring.
+.PP
+The 0th member of the
+.I pmatch
+array is filled in to indicate what substring of
+.I string
+was matched by the entire RE.
+Remaining members report what substring was matched by parenthesized
+subexpressions within the RE;
+member
+.I i
+reports subexpression
+.IR i ,
+with subexpressions counted (starting at 1) by the order of their opening
+parentheses in the RE, left to right.
+Unused entries in the array\(emcorresponding either to subexpressions that
+did not participate in the match at all, or to subexpressions that do not
+exist in the RE (that is, \fIi\fR\ > \fIpreg\fR\->\fIre_nsub\fR)\(emhave both
+.I rm_so
+and
+.I rm_eo
+set to \-1.
+If a subexpression participated in the match several times,
+the reported substring is the last one it matched.
+(Note, as an example in particular, that when the RE `(b*)+' matches `bbb',
+the parenthesized subexpression matches the three `b's and then
+an infinite number of empty strings following the last `b',
+so the reported substring is one of the empties.)
+.PP
+If REG_STARTEND is specified,
+.I pmatch
+must point to at least one
+.I regmatch_t
+(even if
+.I nmatch
+is 0 or REG_NOSUB was specified),
+to hold the input offsets for REG_STARTEND.
+Use for output is still entirely controlled by
+.IR nmatch ;
+if
+.I nmatch
+is 0 or REG_NOSUB was specified,
+the value of
+.IR pmatch [0]
+will not be changed by a successful
+.IR regexec .
+.PP
+.I Regerror
+maps a non-zero
+.I errcode
+from either
+.I regcomp
+or
+.I regexec
+to a human-readable, printable message.
+If
+.I preg
+is non-NULL,
+the error code should have arisen from use of
+the
+.I regex_t
+pointed to by
+.IR preg ,
+and if the error code came from
+.IR regcomp ,
+it should have been the result from the most recent
+.I regcomp
+using that
+.IR regex_t .
+.RI ( Regerror
+may be able to supply a more detailed message using information
+from the
+.IR regex_t .)
+.I Regerror
+places the NUL-terminated message into the buffer pointed to by
+.IR errbuf ,
+limiting the length (including the NUL) to at most
+.I errbuf_size
+bytes.
+If the whole message won't fit,
+as much of it as will fit before the terminating NUL is supplied.
+In any case,
+the returned value is the size of buffer needed to hold the whole
+message (including terminating NUL).
+If
+.I errbuf_size
+is 0,
+.I errbuf
+is ignored but the return value is still correct.
+.PP
+If the
+.I errcode
+given to
+.I regerror
+is first ORed with REG_ITOA,
+the ``message'' that results is the printable name of the error code,
+e.g. ``REG_NOMATCH'',
+rather than an explanation thereof.
+If
+.I errcode
+is REG_ATOI,
+then
+.I preg
+shall be non-NULL and the
+.I re_endp
+member of the structure it points to
+must point to the printable name of an error code;
+in this case, the result in
+.I errbuf
+is the decimal digits of
+the numeric value of the error code
+(0 if the name is not recognized).
+REG_ITOA and REG_ATOI are intended primarily as debugging facilities;
+they are extensions,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+Be warned also that they are considered experimental and changes are possible.
+.PP
+.I Regfree
+frees any dynamically-allocated storage associated with the compiled RE
+pointed to by
+.IR preg .
+The remaining
+.I regex_t
+is no longer a valid compiled RE
+and the effect of supplying it to
+.I regexec
+or
+.I regerror
+is undefined.
+.PP
+None of these functions references global variables except for tables
+of constants;
+all are safe for use from multiple threads if the arguments are safe.
+.SH IMPLEMENTATION CHOICES
+There are a number of decisions that 1003.2 leaves up to the implementor,
+either by explicitly saying ``undefined'' or by virtue of them being
+forbidden by the RE grammar.
+This implementation treats them as follows.
+.PP
+See
+.ZR
+for a discussion of the definition of case-independent matching.
+.PP
+There is no particular limit on the length of REs,
+except insofar as memory is limited.
+Memory usage is approximately linear in RE size, and largely insensitive
+to RE complexity, except for bounded repetitions.
+See BUGS for one short RE using them
+that will run almost any system out of memory.
+.PP
+A backslashed character other than one specifically given a magic meaning
+by 1003.2 (such magic meanings occur only in obsolete [``basic''] REs)
+is taken as an ordinary character.
+.PP
+Any unmatched [ is a REG_EBRACK error.
+.PP
+Equivalence classes cannot begin or end bracket-expression ranges.
+The endpoint of one range cannot begin another.
+.PP
+RE_DUP_MAX, the limit on repetition counts in bounded repetitions, is 255.
+.PP
+A repetition operator (?, *, +, or bounds) cannot follow another
+repetition operator.
+A repetition operator cannot begin an expression or subexpression
+or follow `^' or `|'.
+.PP
+`|' cannot appear first or last in a (sub)expression or after another `|',
+i.e. an operand of `|' cannot be an empty subexpression.
+An empty parenthesized subexpression, `()', is legal and matches an
+empty (sub)string.
+An empty string is not a legal RE.
+.PP
+A `{' followed by a digit is considered the beginning of bounds for a
+bounded repetition, which must then follow the syntax for bounds.
+A `{' \fInot\fR followed by a digit is considered an ordinary character.
+.PP
+`^' and `$' beginning and ending subexpressions in obsolete (``basic'')
+REs are anchors, not ordinary characters.
+.SH SEE ALSO
+grep(1), regex(7)
+.PP
+POSIX 1003.2, sections 2.8 (Regular Expression Notation)
+and
+B.5 (C Binding for Regular Expression Matching).
+.SH DIAGNOSTICS
+Non-zero error codes from
+.I regcomp
+and
+.I regexec
+include the following:
+.PP
+.nf
+.ta \w'REG_ECOLLATE'u+3n
+REG_NOMATCH    regexec() failed to match
+REG_BADPAT     invalid regular expression
+REG_ECOLLATE   invalid collating element
+REG_ECTYPE     invalid character class
+REG_EESCAPE    \e applied to unescapable character
+REG_ESUBREG    invalid backreference number
+REG_EBRACK     brackets [ ] not balanced
+REG_EPAREN     parentheses ( ) not balanced
+REG_EBRACE     braces { } not balanced
+REG_BADBR      invalid repetition count(s) in { }
+REG_ERANGE     invalid character range in [ ]
+REG_ESPACE     ran out of memory
+REG_BADRPT     ?, *, or + operand invalid
+REG_EMPTY      empty (sub)expression
+REG_ASSERT     ``can't happen''\(emyou found a bug
+REG_INVARG     invalid argument, e.g. negative-length string
+.fi
+.SH HISTORY
+Written by Henry Spencer,
+henry@zoo.toronto.edu.
+.SH BUGS
+This is an alpha release with known defects.
+Please report problems.
+.PP
+There is one known functionality bug.
+The implementation of internationalization is incomplete:
+the locale is always assumed to be the default one of 1003.2,
+and only the collating elements etc. of that locale are available.
+.PP
+The back-reference code is subtle and doubts linger about its correctness
+in complex cases.
+.PP
+.I Regexec
+performance is poor.
+This will improve with later releases.
+.I Nmatch
+exceeding 0 is expensive;
+.I nmatch
+exceeding 1 is worse.
+.I Regexec
+is largely insensitive to RE complexity \fIexcept\fR that back
+references are massively expensive.
+RE length does matter; in particular, there is a strong speed bonus
+for keeping RE length under about 30 characters,
+with most special characters counting roughly double.
+.PP
+.I Regcomp
+implements bounded repetitions by macro expansion,
+which is costly in time and space if counts are large
+or bounded repetitions are nested.
+An RE like, say,
+`((((a{1,100}){1,100}){1,100}){1,100}){1,100}'
+will (eventually) run almost any existing machine out of swap space.
+.PP
+There are suspected problems with response to obscure error conditions.
+Notably,
+certain kinds of internal overflow,
+produced only by truly enormous REs or by multiply nested bounded repetitions,
+are probably not handled well.
+.PP
+Due to a mistake in 1003.2, things like `a)b' are legal REs because `)' is
+a special character only in the presence of a previous unmatched `('.
+This can't be fixed until the spec is fixed.
+.PP
+The standard's definition of back references is vague.
+For example, does
+`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?
+Until the standard is clarified,
+behavior in such cases should not be relied on.
+.PP
+The implementation of word-boundary matching is a bit of a kludge,
+and bugs may lurk in combinations of word-boundary matching and anchoring.
diff --git a/regex-src/regex.7 b/regex-src/regex.7
new file mode 100644 (file)
index 0000000..0fa1802
--- /dev/null
@@ -0,0 +1,235 @@
+.TH REGEX 7 "25 Oct 1995"
+.BY "Henry Spencer"
+.SH NAME
+regex \- POSIX 1003.2 regular expressions
+.SH DESCRIPTION
+Regular expressions (``RE''s),
+as defined in POSIX 1003.2, come in two forms:
+modern REs (roughly those of
+.IR egrep ;
+1003.2 calls these ``extended'' REs)
+and obsolete REs (roughly those of
+.IR ed ;
+1003.2 ``basic'' REs).
+Obsolete REs mostly exist for backward compatibility in some old programs;
+they will be discussed at the end.
+1003.2 leaves some aspects of RE syntax and semantics open;
+`\(dg' marks decisions on these aspects that
+may not be fully portable to other 1003.2 implementations.
+.PP
+A (modern) RE is one\(dg or more non-empty\(dg \fIbranches\fR,
+separated by `|'.
+It matches anything that matches one of the branches.
+.PP
+A branch is one\(dg or more \fIpieces\fR, concatenated.
+It matches a match for the first, followed by a match for the second, etc.
+.PP
+A piece is an \fIatom\fR possibly followed
+by a single\(dg `*', `+', `?', or \fIbound\fR.
+An atom followed by `*' matches a sequence of 0 or more matches of the atom.
+An atom followed by `+' matches a sequence of 1 or more matches of the atom.
+An atom followed by `?' matches a sequence of 0 or 1 matches of the atom.
+.PP
+A \fIbound\fR is `{' followed by an unsigned decimal integer,
+possibly followed by `,'
+possibly followed by another unsigned decimal integer,
+always followed by `}'.
+The integers must lie between 0 and RE_DUP_MAX (255\(dg) inclusive,
+and if there are two of them, the first may not exceed the second.
+An atom followed by a bound containing one integer \fIi\fR
+and no comma matches
+a sequence of exactly \fIi\fR matches of the atom.
+An atom followed by a bound
+containing one integer \fIi\fR and a comma matches
+a sequence of \fIi\fR or more matches of the atom.
+An atom followed by a bound
+containing two integers \fIi\fR and \fIj\fR matches
+a sequence of \fIi\fR through \fIj\fR (inclusive) matches of the atom.
+.PP
+An atom is a regular expression enclosed in `()' (matching a match for the
+regular expression),
+an empty set of `()' (matching the null string)\(dg,
+a \fIbracket expression\fR (see below), `.'
+(matching any single character), `^' (matching the null string at the
+beginning of a line), `$' (matching the null string at the
+end of a line), a `\e' followed by one of the characters
+`^.[$()|*+?{\e'
+(matching that character taken as an ordinary character),
+a `\e' followed by any other character\(dg
+(matching that character taken as an ordinary character,
+as if the `\e' had not been present\(dg),
+or a single character with no other significance (matching that character).
+A `{' followed by a character other than a digit is an ordinary
+character, not the beginning of a bound\(dg.
+It is illegal to end an RE with `\e'.
+.PP
+A \fIbracket expression\fR is a list of characters enclosed in `[]'.
+It normally matches any single character from the list (but see below).
+If the list begins with `^',
+it matches any single character
+(but see below) \fInot\fR from the rest of the list.
+If two characters in the list are separated by `\-', this is shorthand
+for the full \fIrange\fR of characters between those two (inclusive) in the
+collating sequence,
+e.g. `[0\-9]' in ASCII matches any decimal digit.
+It is illegal\(dg for two ranges to share an
+endpoint, e.g. `a\-c\-e'.
+Ranges are very collating-sequence-dependent,
+and portable programs should avoid relying on them.
+.PP
+To include a literal `]' in the list, make it the first character
+(following a possible `^').
+To include a literal `\-', make it the first or last character,
+or the second endpoint of a range.
+To use a literal `\-' as the first endpoint of a range,
+enclose it in `[.' and `.]' to make it a collating element (see below).
+With the exception of these and some combinations using `[' (see next
+paragraphs), all other special characters, including `\e', lose their
+special significance within a bracket expression.
+.PP
+Within a bracket expression, a collating element (a character,
+a multi-character sequence that collates as if it were a single character,
+or a collating-sequence name for either)
+enclosed in `[.' and `.]' stands for the
+sequence of characters of that collating element.
+The sequence is a single element of the bracket expression's list.
+A bracket expression containing a multi-character collating element 
+can thus match more than one character,
+e.g. if the collating sequence includes a `ch' collating element,
+then the RE `[[.ch.]]*c' matches the first five characters
+of `chchcc'.
+.PP
+Within a bracket expression, a collating element enclosed in `[=' and
+`=]' is an equivalence class, standing for the sequences of characters
+of all collating elements equivalent to that one, including itself.
+(If there are no other equivalent collating elements,
+the treatment is as if the enclosing delimiters were `[.' and `.]'.)
+For example, if o and \o'o^' are the members of an equivalence class,
+then `[[=o=]]', `[[=\o'o^'=]]', and `[o\o'o^']' are all synonymous.
+An equivalence class may not\(dg be an endpoint
+of a range.
+.PP
+Within a bracket expression, the name of a \fIcharacter class\fR enclosed
+in `[:' and `:]' stands for the list of all characters belonging to that
+class.
+Standard character class names are:
+.PP
+.RS
+.nf
+.ta 3c 6c 9c
+alnum  digit   punct
+alpha  graph   space
+blank  lower   upper
+cntrl  print   xdigit
+.fi
+.RE
+.PP
+These stand for the character classes defined in
+.IR ctype (3).
+A locale may provide others.
+A character class may not be used as an endpoint of a range.
+.PP
+There are two special cases\(dg of bracket expressions:
+the bracket expressions `[[:<:]]' and `[[:>:]]' match the null string at
+the beginning and end of a word respectively.
+A word is defined as a sequence of
+word characters
+which is neither preceded nor followed by
+word characters.
+A word character is an
+.I alnum
+character (as defined by
+.IR ctype (3))
+or an underscore.
+This is an extension,
+compatible with but not specified by POSIX 1003.2,
+and should be used with
+caution in software intended to be portable to other systems.
+.PP
+In the event that an RE could match more than one substring of a given
+string,
+the RE matches the one starting earliest in the string.
+If the RE could match more than one substring starting at that point,
+it matches the longest.
+Subexpressions also match the longest possible substrings, subject to
+the constraint that the whole match be as long as possible,
+with subexpressions starting earlier in the RE taking priority over
+ones starting later.
+Note that higher-level subexpressions thus take priority over
+their lower-level component subexpressions.
+.PP
+Match lengths are measured in characters, not collating elements.
+A null string is considered longer than no match at all.
+For example,
+`bb*' matches the three middle characters of `abbbc',
+`(wee|week)(knights|nights)' matches all ten characters of `weeknights',
+when `(.*).*' is matched against `abc' the parenthesized subexpression
+matches all three characters, and
+when `(a*)*' is matched against `bc' both the whole RE and the parenthesized
+subexpression match the null string.
+.PP
+If case-independent matching is specified,
+the effect is much as if all case distinctions had vanished from the
+alphabet.
+When an alphabetic that exists in multiple cases appears as an
+ordinary character outside a bracket expression, it is effectively
+transformed into a bracket expression containing both cases,
+e.g. `x' becomes `[xX]'.
+When it appears inside a bracket expression, all case counterparts
+of it are added to the bracket expression, so that (e.g.) `[x]'
+becomes `[xX]' and `[^x]' becomes `[^xX]'.
+.PP
+No particular limit is imposed on the length of REs\(dg.
+Programs intended to be portable should not employ REs longer
+than 256 bytes,
+as an implementation can refuse to accept such REs and remain
+POSIX-compliant.
+.PP
+Obsolete (``basic'') regular expressions differ in several respects.
+`|', `+', and `?' are ordinary characters and there is no equivalent
+for their functionality.
+The delimiters for bounds are `\e{' and `\e}',
+with `{' and `}' by themselves ordinary characters.
+The parentheses for nested subexpressions are `\e(' and `\e)',
+with `(' and `)' by themselves ordinary characters.
+`^' is an ordinary character except at the beginning of the
+RE or\(dg the beginning of a parenthesized subexpression,
+`$' is an ordinary character except at the end of the
+RE or\(dg the end of a parenthesized subexpression,
+and `*' is an ordinary character if it appears at the beginning of the
+RE or the beginning of a parenthesized subexpression
+(after a possible leading `^').
+Finally, there is one new type of atom, a \fIback reference\fR:
+`\e' followed by a non-zero decimal digit \fId\fR
+matches the same sequence of characters
+matched by the \fId\fRth parenthesized subexpression
+(numbering subexpressions by the positions of their opening parentheses,
+left to right),
+so that (e.g.) `\e([bc]\e)\e1' matches `bb' or `cc' but not `bc'.
+.SH SEE ALSO
+regex(3)
+.PP
+POSIX 1003.2, section 2.8 (Regular Expression Notation).
+.SH HISTORY
+Written by Henry Spencer, based on the 1003.2 spec.
+.SH BUGS
+Having two kinds of REs is a botch.
+.PP
+The current 1003.2 spec says that `)' is an ordinary character in
+the absence of an unmatched `(';
+this was an unintentional result of a wording error,
+and change is likely.
+Avoid relying on it.
+.PP
+Back references are a dreadful botch,
+posing major problems for efficient implementations.
+They are also somewhat vaguely defined
+(does
+`a\e(\e(b\e)*\e2\e)*d' match `abbbd'?).
+Avoid using them.
+.PP
+1003.2's specification of case-independent matching is vague.
+The ``one case implies all cases'' definition given above
+is current consensus among implementors as to the right interpretation.
+.PP
+The syntax for word boundaries is incredibly ugly.
diff --git a/regex-src/regex2.h b/regex-src/regex2.h
new file mode 100644 (file)
index 0000000..56bb1f9
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * First, the stuff that ends up in the outside-world include file
+ = typedef off_t regoff_t;
+ = typedef struct {
+ =     int re_magic;
+ =     size_t re_nsub;         // number of parenthesized subexpressions
+ =     const char *re_endp;    // end pointer for REG_PEND
+ =     struct re_guts *re_g;   // none of your business :-)
+ = } regex_t;
+ = typedef struct {
+ =     regoff_t rm_so;         // start of match
+ =     regoff_t rm_eo;         // end of match
+ = } regmatch_t;
+ */
+/*
+ * internals of regex_t
+ */
+#define        MAGIC1  ((('r'^0200)<<8) | 'e')
+
+/*
+ * The internal representation is a *strip*, a sequence of
+ * operators ending with an endmarker.  (Some terminology etc. is a
+ * historical relic of earlier versions which used multiple strips.)
+ * Certain oddities in the representation are there to permit running
+ * the machinery backwards; in particular, any deviation from sequential
+ * flow must be marked at both its source and its destination.  Some
+ * fine points:
+ *
+ * - OPLUS_ and O_PLUS are *inside* the loop they create.
+ * - OQUEST_ and O_QUEST are *outside* the bypass they create.
+ * - OCH_ and O_CH are *outside* the multi-way branch they create, while
+ *   OOR1 and OOR2 are respectively the end and the beginning of one of
+ *   the branches.  Note that there is an implicit OOR2 following OCH_
+ *   and an implicit OOR1 preceding O_CH.
+ *
+ * In state representations, an operator's bit is on to signify a state
+ * immediately *preceding* "execution" of that operator.
+ */
+typedef unsigned long sop;     /* strip operator */
+typedef long sopno;
+#define        OPRMASK 0xf8000000
+#define        OPDMASK 0x07ffffff
+#define        OPSHIFT ((unsigned)27)
+#define        OP(n)   ((n)&OPRMASK)
+#define        OPND(n) ((n)&OPDMASK)
+#define        SOP(op, opnd)   ((op)|(opnd))
+
+#ifndef UNSIGNEDLONG1
+#ifndef NO_UL_CNSTS
+#define UNSIGNEDLONG1 1ul
+#else
+#define UNSIGNEDLONG1 ((unsigned long)1)
+#endif
+#endif
+
+#define MAKE_UNSIGNED_LONG(num) (UNSIGNEDLONG1*num)
+#define SHIFTED_UL(num) (MAKE_UNSIGNED_LONG(num) << OPSHIFT)
+
+/* operators                      meaning      operand                 */
+/*                                             (back, fwd are offsets) */
+#define        OEND    (SHIFTED_UL(1)) /* endmarker    -                       */
+#define        OCHAR   (SHIFTED_UL(2)) /* character    unsigned char           */
+#define        OBOL    (SHIFTED_UL(3)) /* left anchor  -                       */
+#define        OEOL    (SHIFTED_UL(4)) /* right anchor -                       */
+#define        OANY    (SHIFTED_UL(5)) /* .            -                       */
+#define        OANYOF  (SHIFTED_UL(6)) /* [...]        set number              */
+#define        OBACK_  (SHIFTED_UL(7)) /* begin \d     paren number            */
+#define        O_BACK  (SHIFTED_UL(8)) /* end \d       paren number            */
+#define        OPLUS_  (SHIFTED_UL(9)) /* + prefix     fwd to suffix           */
+#define        O_PLUS  (SHIFTED_UL(10))        /* + suffix     back to prefix          */
+#define        OQUEST_ (SHIFTED_UL(11))        /* ? prefix     fwd to suffix           */
+#define        O_QUEST (SHIFTED_UL(12))        /* ? suffix     back to prefix          */
+#define        OLPAREN (SHIFTED_UL(13))        /* (            fwd to )                */
+#define        ORPAREN (SHIFTED_UL(14))        /* )            back to (               */
+#define        OCH_    (SHIFTED_UL(15))        /* begin choice fwd to OOR2             */
+#define        OOR1    (SHIFTED_UL(16))        /* | pt. 1      back to OOR1 or OCH_    */
+#define        OOR2    (SHIFTED_UL(17))        /* | pt. 2      fwd to OOR2 or O_CH     */
+#define        O_CH    (SHIFTED_UL(18))        /* end choice   back to OOR1            */
+#define        OBOW    (SHIFTED_UL(19))        /* begin word   -                       */
+#define        OEOW    (SHIFTED_UL(20))        /* end word     -                       */
+
+/*
+ * Structure for [] character-set representation.  Character sets are
+ * done as bit vectors, grouped 8 to a byte vector for compactness.
+ * The individual set therefore has both a pointer to the byte vector
+ * and a mask to pick out the relevant bit of each byte.  A hash code
+ * simplifies testing whether two sets could be identical.
+ *
+ * This will get trickier for multicharacter collating elements.  As
+ * preliminary hooks for dealing with such things, we also carry along
+ * a string of multi-character elements, and decide the size of the
+ * vectors at run time.
+ */
+typedef struct {
+       uch *ptr;               /* -> uch [csetsize] */
+       uch mask;               /* bit within array */
+       uch hash;               /* hash code */
+       size_t smultis;
+       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        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)
+#define        MCin(p, cs, cp) mcin(p, cs, cp)
+
+/* stuff for character categories */
+typedef unsigned char cat_t;
+
+/*
+ * main compiled-expression structure
+ */
+struct re_guts {
+       int magic;
+#              define  MAGIC2  ((('R'^0200)<<8)|'E')
+       sop *strip;             /* malloced area for strip */
+       int csetsize;           /* number of bits in a cset vector */
+       int ncsets;             /* number of csets in use */
+       cset *sets;             /* -> cset [ncsets] */
+       uch *setbits;           /* -> uch[csetsize][ncsets/CHAR_BIT] */
+       int cflags;             /* copy of regcomp() cflags argument */
+       sopno nstates;          /* = number of sops */
+       sopno firststate;       /* the initial OEND (normally 0) */
+       sopno laststate;        /* the final OEND */
+       int iflags;             /* internal flags */
+#              define  USEBOL  01      /* used ^ */
+#              define  USEEOL  02      /* used $ */
+#              define  BAD     04      /* something wrong */
+       int nbol;               /* number of ^ used */
+       int neol;               /* number of $ used */
+       int ncategories;        /* how many character categories */
+       cat_t *categories;      /* ->catspace[-CHAR_MIN] */
+       char *must;             /* match must contain this string */
+       int 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? */
+       /* catspace must be last */
+       cat_t catspace[1];      /* actually [NC] */
+};
+
+/* misc utilities */
+#define        OUT     (CHAR_MAX+1)    /* a non-character value */
+#define        ISWORD(c)       (isalnum(c) || (c) == '_')
diff --git a/regex-src/regexec.c b/regex-src/regexec.c
new file mode 100644 (file)
index 0000000..71c6d3a
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * the outer shell of regexec()
+ *
+ * This file includes engine.c *twice*, after muchos fiddling with the
+ * 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 <regex.h>
+
+#include "utils.h"
+#include "regex2.h"
+
+static int nope = 0;           /* for use in asserts; shuts lint up */
+
+/* macros for manipulating states, small version */
+#define        states  long
+#define        states1 states          /* for later use in regexec() decision */
+#define        CLEAR(v)        ((v) = 0)
+#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        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        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)))
+/* function names */
+#define SNAMES                 /* engine.c looks after details */
+
+#include "engine.c"
+
+/* now undo things */
+#undef states
+#undef CLEAR
+#undef SET0
+#undef SET1
+#undef ISSET
+#undef ASSIGN
+#undef EQ
+#undef STATEVARS
+#undef STATESETUP
+#undef STATETEARDOWN
+#undef SETUP
+#undef onestate
+#undef INIT
+#undef INC
+#undef ISSTATEIN
+#undef FWD
+#undef BACK
+#undef ISSETBACK
+#undef SNAMES
+
+/* macros for manipulating states, large version */
+#define        states  char *
+#define        CLEAR(v)        memset(v, 0, 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        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        STATETEARDOWN(m)        { free((m)->space); }
+#define        SETUP(v)        ((v) = &m->space[m->vn++ * m->g->nstates])
+#define        onestate        int
+#define        INIT(o, n)      ((o) = (n))
+#define        INC(o)  ((o)++)
+#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)[here+(n)] |= (src)[here])
+#define        BACK(dst, src, n)       ((dst)[here-(n)] |= (src)[here])
+#define        ISSETBACK(v, n) ((v)[here - (n)])
+/* function names */
+#define        LNAMES                  /* flag */
+
+#include "engine.c"
+
+/*
+ - regexec - interface for matching
+ = extern int regexec(const regex_t *, const char *, size_t, \
+ =                                     regmatch_t [], int);
+ = #define     REG_NOTBOL      00001
+ = #define     REG_NOTEOL      00002
+ = #define     REG_STARTEND    00004
+ = #define     REG_TRACE       00400   // tracing of execution
+ = #define     REG_LARGE       01000   // force large representation
+ = #define     REG_BACKR       02000   // force use of backref code
+ *
+ * We put this here so we can exploit knowledge of the state representation
+ * when choosing which matcher to call.  Also, by this point the matchers
+ * 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;
+{
+       register struct re_guts *g = preg->re_g;
+#ifdef REDEBUG
+#      define  GOODFLAGS(f)    (f)
+#else
+#      define  GOODFLAGS(f)    ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
+#endif
+
+       if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
+               return(REG_BADPAT);
+       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))
+               return(smatcher(g, (char *)string, nmatch, pmatch, eflags));
+       else
+               return(lmatcher(g, (char *)string, nmatch, pmatch, eflags));
+}
diff --git a/regex-src/regfree.c b/regex-src/regfree.c
new file mode 100644 (file)
index 0000000..9a6acf1
--- /dev/null
@@ -0,0 +1,37 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "utils.h"
+#include "regex2.h"
+
+/*
+ - regfree - free everything
+ = extern void regfree(regex_t *);
+ */
+void
+regfree(preg)
+regex_t *preg;
+{
+       register struct re_guts *g;
+
+       if (preg->re_magic != MAGIC1)   /* oops */
+               return;                 /* nice to complain, but hard */
+
+       g = preg->re_g;
+       if (g == NULL || g->magic != MAGIC2)    /* oops again */
+               return;
+       preg->re_magic = 0;             /* mark it invalid */
+       g->magic = 0;                   /* mark it invalid */
+
+       if (g->strip != NULL)
+               free((char *)g->strip);
+       if (g->sets != NULL)
+               free((char *)g->sets);
+       if (g->setbits != NULL)
+               free((char *)g->setbits);
+       if (g->must != NULL)
+               free(g->must);
+       free((char *)g);
+}
diff --git a/regex-src/split.c b/regex-src/split.c
new file mode 100644 (file)
index 0000000..9e3e11a
--- /dev/null
@@ -0,0 +1,319 @@
+#include <stdio.h>
+#include <string.h>
+
+/*
+ - split - divide a string into fields, like awk split()
+ = 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]+ */
+{
+       register char *p = string;
+       register char c;                        /* latest character */
+       register char sepc = sep[0];
+       register char sepc2;
+       register int fn;
+       register char **fp = fields;
+       register char *sepp;
+       register int trimtrail;
+
+       /* white space */
+       if (sepc == '\0') {
+               while ((c = *p++) == ' ' || c == '\t')
+                       continue;
+               p--;
+               trimtrail = 1;
+               sep = " \t";    /* note, code below knows this is 2 long */
+               sepc = ' ';
+       } else
+               trimtrail = 0;
+       sepc2 = sep[1];         /* now we can safely pick this up */
+
+       /* catch empties */
+       if (*p == '\0')
+               return(0);
+
+       /* single separator */
+       if (sepc2 == '\0') {
+               fn = nfields;
+               for (;;) {
+                       *fp++ = p;
+                       fn--;
+                       if (fn == 0)
+                               break;
+                       while ((c = *p++) != sepc)
+                               if (c == '\0')
+                                       return(nfields - fn);
+                       *(p-1) = '\0';
+               }
+               /* we have overflowed the fields vector -- just count them */
+               fn = nfields;
+               for (;;) {
+                       while ((c = *p++) != sepc)
+                               if (c == '\0')
+                                       return(fn);
+                       fn++;
+               }
+               /* not reached */
+       }
+
+       /* two separators */
+       if (sep[2] == '\0') {
+               fn = nfields;
+               for (;;) {
+                       *fp++ = p;
+                       fn--;
+                       while ((c = *p++) != sepc && c != sepc2)
+                               if (c == '\0') {
+                                       if (trimtrail && **(fp-1) == '\0')
+                                               fn++;
+                                       return(nfields - fn);
+                               }
+                       if (fn == 0)
+                               break;
+                       *(p-1) = '\0';
+                       while ((c = *p++) == sepc || c == sepc2)
+                               continue;
+                       p--;
+               }
+               /* we have overflowed the fields vector -- just count them */
+               fn = nfields;
+               while (c != '\0') {
+                       while ((c = *p++) == sepc || c == sepc2)
+                               continue;
+                       p--;
+                       fn++;
+                       while ((c = *p++) != '\0' && c != sepc && c != sepc2)
+                               continue;
+               }
+               /* might have to trim trailing white space */
+               if (trimtrail) {
+                       p--;
+                       while ((c = *--p) == sepc || c == sepc2)
+                               continue;
+                       p++;
+                       if (*p != '\0') {
+                               if (fn == nfields+1)
+                                       *p = '\0';
+                               fn--;
+                       }
+               }
+               return(fn);
+       }
+
+       /* n separators */
+       fn = 0;
+       for (;;) {
+               if (fn < nfields)
+                       *fp++ = p;
+               fn++;
+               for (;;) {
+                       c = *p++;
+                       if (c == '\0')
+                               return(fn);
+                       sepp = sep;
+                       while ((sepc = *sepp++) != '\0' && sepc != c)
+                               continue;
+                       if (sepc != '\0')       /* it was a separator */
+                               break;
+               }
+               if (fn < nfields)
+                       *(p-1) = '\0';
+               for (;;) {
+                       c = *p++;
+                       sepp = sep;
+                       while ((sepc = *sepp++) != '\0' && sepc != c)
+                               continue;
+                       if (sepc == '\0')       /* it wasn't a separator */
+                               break;
+               }
+               p--;
+       }
+
+       /* not reached */
+}
+
+#ifdef TEST_SPLIT
+
+
+/*
+ * test program
+ * pgm         runs regression
+ * pgm sep     splits stdin lines by sep
+ * pgm str sep splits str by sep
+ * pgm str sep n       splits str by sep n times
+ */
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+       char buf[512];
+       register int n;
+#      define  MNF     10
+       char *fields[MNF];
+
+       if (argc > 4)
+               for (n = atoi(argv[3]); n > 0; n--) {
+                       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';
+                       (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) {
+                       buf[strlen(buf)-1] = '\0';      /* stomp newline */
+                       dosplit(buf, argv[1]);
+               }
+       else
+               regress();
+
+       exit(0);
+}
+
+dosplit(string, seps)
+char *string;
+char *seps;
+{
+#      define  NF      5
+       char *fields[NF];
+       register int nf;
+
+       nf = split(string, fields, NF, seps);
+       print(nf, NF, fields);
+}
+
+print(nf, nfp, fields)
+int nf;
+int nfp;
+char *fields[];
+{
+       register int fn;
+       register int bound;
+
+       bound = (nf > nfp) ? nfp : nf;
+       printf("%d:\t", nf);
+       for (fn = 0; fn < bound; fn++)
+               printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n");
+}
+
+#define        RNF     5               /* some table entries know this */
+struct {
+       char *str;
+       char *seps;
+       int nf;
+       char *fi[RNF];
+} tests[] = {
+       "",             " ",    0,      { "" },
+       " ",            " ",    2,      { "", "" },
+       "x",            " ",    1,      { "x" },
+       "xy",           " ",    1,      { "xy" },
+       "x y",          " ",    2,      { "x", "y" },
+       "abc def  g ",  " ",    5,      { "abc", "def", "", "g", "" },
+       "  a bcd",      " ",    4,      { "", "", "a", "bcd" },
+       "a b c d e f",  " ",    6,      { "a", "b", "c", "d", "e f" },
+       " a b c d ",    " ",    6,      { "", "a", "b", "c", "d " },
+
+       "",             " _",   0,      { "" },
+       " ",            " _",   2,      { "", "" },
+       "x",            " _",   1,      { "x" },
+       "x y",          " _",   2,      { "x", "y" },
+       "ab _ cd",      " _",   2,      { "ab", "cd" },
+       " a_b  c ",     " _",   5,      { "", "a", "b", "c", "" },
+       "a b c_d e f",  " _",   6,      { "a", "b", "c", "d", "e f" },
+       " a b c d ",    " _",   6,      { "", "a", "b", "c", "d " },
+
+       "",             " _~",  0,      { "" },
+       " ",            " _~",  2,      { "", "" },
+       "x",            " _~",  1,      { "x" },
+       "x y",          " _~",  2,      { "x", "y" },
+       "ab _~ cd",     " _~",  2,      { "ab", "cd" },
+       " a_b  c~",     " _~",  5,      { "", "a", "b", "c", "" },
+       "a b_c d~e f",  " _~",  6,      { "a", "b", "c", "d", "e f" },
+       "~a b c d ",    " _~",  6,      { "", "a", "b", "c", "d " },
+
+       "",             " _~-", 0,      { "" },
+       " ",            " _~-", 2,      { "", "" },
+       "x",            " _~-", 1,      { "x" },
+       "x y",          " _~-", 2,      { "x", "y" },
+       "ab _~- cd",    " _~-", 2,      { "ab", "cd" },
+       " a_b  c~",     " _~-", 5,      { "", "a", "b", "c", "" },
+       "a b_c-d~e f",  " _~-", 6,      { "a", "b", "c", "d", "e f" },
+       "~a-b c d ",    " _~-", 6,      { "", "a", "b", "c", "d " },
+
+       "",             "  ",   0,      { "" },
+       " ",            "  ",   2,      { "", "" },
+       "x",            "  ",   1,      { "x" },
+       "xy",           "  ",   1,      { "xy" },
+       "x y",          "  ",   2,      { "x", "y" },
+       "abc def  g ",  "  ",   4,      { "abc", "def", "g", "" },
+       "  a bcd",      "  ",   3,      { "", "a", "bcd" },
+       "a b c d e f",  "  ",   6,      { "a", "b", "c", "d", "e f" },
+       " a b c d ",    "  ",   6,      { "", "a", "b", "c", "d " },
+
+       "",             "",     0,      { "" },
+       " ",            "",     0,      { "" },
+       "x",            "",     1,      { "x" },
+       "xy",           "",     1,      { "xy" },
+       "x y",          "",     2,      { "x", "y" },
+       "abc def  g ",  "",     3,      { "abc", "def", "g" },
+       "\t a bcd",     "",     2,      { "a", "bcd" },
+       "  a \tb\t c ", "",     3,      { "a", "b", "c" },
+       "a b c d e ",   "",     5,      { "a", "b", "c", "d", "e" },
+       "a b\tc d e f", "",     6,      { "a", "b", "c", "d", "e f" },
+       " a b c d e f ",        "",     6,      { "a", "b", "c", "d", "e f " },
+
+       NULL,           NULL,   0,      { NULL },
+};
+
+regress()
+{
+       char buf[512];
+       register int n;
+       char *fields[RNF+1];
+       register int nf;
+       register int i;
+       register int printit;
+       register char *f;
+
+       for (n = 0; tests[n].str != NULL; n++) {
+               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;
+               if (nf != tests[n].nf) {
+                       printf("split `%s' by `%s' gave %d fields, not %d\n",
+                               tests[n].str, tests[n].seps, nf, tests[n].nf);
+                       printit = 1;
+               } else if (fields[RNF] != NULL) {
+                       printf("split() went beyond array end\n");
+                       printit = 1;
+               } else {
+                       for (i = 0; i < nf && i < RNF; i++) {
+                               f = fields[i];
+                               if (f == NULL)
+                                       f = "(NULL)";
+                               if (strcmp(f, tests[n].fi[i]) != 0) {
+                                       printf("split `%s' by `%s', field %d is `%s', not `%s'\n",
+                                               tests[n].str, tests[n].seps,
+                                               i, fields[i], tests[n].fi[i]);
+                                       printit = 1;
+                               }
+                       }
+               }
+               if (printit)
+                       print(nf, RNF, fields);
+       }
+}
+#endif
diff --git a/regex-src/tests b/regex-src/tests
new file mode 100644 (file)
index 0000000..0de9118
--- /dev/null
@@ -0,0 +1,476 @@
+# regular expression test set
+# Lines are at least three fields, separated by one or more tabs.  "" stands
+# for an empty field.  First field is an RE.  Second field is flags.  If
+# C flag given, regcomp() is expected to fail, and the third field is the
+# error name (minus the leading REG_).
+#
+# Otherwise it is expected to succeed, and the third field is the string to
+# try matching it against.  If there is no fourth field, the match is
+# expected to fail.  If there is a fourth field, it is the substring that
+# the RE is expected to match.  If there is a fifth field, it is a comma-
+# separated list of what the subexpressions should match, with - indicating
+# no match for that one.  In both the fourth and fifth fields, a (sub)field
+# starting with @ indicates that the (sub)expression is expected to match
+# a null string followed by the stuff after the @; this provides a way to
+# test where null strings match.  The character `N' in REs and strings
+# is newline, `S' is space, `T' is tab, `Z' is NUL.
+#
+# The full list of flags:
+#      -       placeholder, does nothing
+#      b       RE is a BRE, not an ERE
+#      &       try it as both an ERE and a BRE
+#      C       regcomp() error expected, third field is error name
+#      i       REG_ICASE
+#      m       ("mundane") REG_NOSPEC
+#      s       REG_NOSUB (not really testable)
+#      n       REG_NEWLINE
+#      ^       REG_NOTBOL
+#      $       REG_NOTEOL
+#      #       REG_STARTEND (see below)
+#      p       REG_PEND
+#
+# For REG_STARTEND, the start/end offsets are those of the substring
+# enclosed in ().
+
+# basics
+a              &       a       a
+abc            &       abc     abc
+abc|de         -       abc     abc
+a|b|c          -       abc     a
+
+# parentheses and perversions thereof
+a(b)c          -       abc     abc
+a\(b\)c                b       abc     abc
+a(             C       EPAREN
+a(             b       a(      a(
+a\(            -       a(      a(
+a\(            bC      EPAREN
+a\(b           bC      EPAREN
+a(b            C       EPAREN
+a(b            b       a(b     a(b
+# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly)
+a)             -       a)      a)
+)              -       )       )
+# end gagging (in a just world, those *should* give EPAREN)
+a)             b       a)      a)
+a\)            bC      EPAREN
+\)             bC      EPAREN
+a()b           -       ab      ab
+a\(\)b         b       ab      ab
+
+# anchoring and REG_NEWLINE
+^abc$          &       abc     abc
+a^b            -       a^b
+a^b            b       a^b     a^b
+a$b            -       a$b
+a$b            b       a$b     a$b
+^              &       abc     @abc
+$              &       abc     @
+^$             &       ""      @
+$^             -       ""      @
+\($\)\(^\)     b       ""      @
+# stop retching, those are legitimate (although disgusting)
+^^             -       ""      @
+$$             -       ""      @
+b$             &       abNc
+b$             &n      abNc    b
+^b$            &       aNbNc
+^b$            &n      aNbNc   b
+^$             &n      aNNb    @Nb
+^$             n       abc
+^$             n       abcN    @
+$^             n       aNNb    @Nb
+\($\)\(^\)     bn      aNNb    @Nb
+^^             n^      aNNb    @Nb
+$$             n       aNNb    @NN
+^a             ^       a
+a$             $       a
+^a             ^n      aNb
+^b             ^n      aNb     b
+a$             $n      bNa
+b$             $n      bNa     b
+a*(^b$)c*      -       b       b
+a*\(^b$\)c*    b       b       b
+
+# certain syntax errors and non-errors
+|              C       EMPTY
+|              b       |       |
+*              C       BADRPT
+*              b       *       *
++              C       BADRPT
+?              C       BADRPT
+""             &C      EMPTY
+()             -       abc     @abc
+\(\)           b       abc     @abc
+a||b           C       EMPTY
+|ab            C       EMPTY
+ab|            C       EMPTY
+(|a)b          C       EMPTY
+(a|)b          C       EMPTY
+(*a)           C       BADRPT
+(+a)           C       BADRPT
+(?a)           C       BADRPT
+({1}a)         C       BADRPT
+\(\{1\}a\)     bC      BADRPT
+(a|*b)         C       BADRPT
+(a|+b)         C       BADRPT
+(a|?b)         C       BADRPT
+(a|{1}b)       C       BADRPT
+^*             C       BADRPT
+^*             b       *       *
+^+             C       BADRPT
+^?             C       BADRPT
+^{1}           C       BADRPT
+^\{1\}         bC      BADRPT
+
+# metacharacters, backslashes
+a.c            &       abc     abc
+a[bc]d         &       abd     abd
+a\*c           &       a*c     a*c
+a\\b           &       a\b     a\b
+a\\\*b         &       a\*b    a\*b
+a\bc           &       abc     abc
+a\             &C      EESCAPE
+a\\bc          &       a\bc    a\bc
+\{             bC      BADRPT
+a\[b           &       a[b     a[b
+a[b            &C      EBRACK
+# trailing $ is a peculiar special case for the BRE code
+a$             &       a       a
+a$             &       a$
+a\$            &       a
+a\$            &       a$      a$
+a\\$           &       a
+a\\$           &       a$
+a\\$           &       a\$
+a\\$           &       a\      a\
+
+# back references, ugh
+a\(b\)\2c      bC      ESUBREG
+a\(b\1\)c      bC      ESUBREG
+a\(b*\)c\1d    b       abbcbbd abbcbbd bb
+a\(b*\)c\1d    b       abbcbd
+a\(b*\)c\1d    b       abbcbbbd
+^\(.\)\1       b       abc
+a\([bc]\)\1d   b       abcdabbd        abbd    b
+a\(\([bc]\)\2\)*d      b       abbccd  abbccd
+a\(\([bc]\)\2\)*d      b       abbcbd
+# actually, this next one probably ought to fail, but the spec is unclear
+a\(\(b\)*\2\)*d                b       abbbd   abbbd
+# here is a case that no NFA implementation does right
+\(ab*\)[ab]*\1 b       ababaaa ababaaa a
+# check out normal matching in the presence of back refs
+\(a\)\1bcd     b       aabcd   aabcd
+\(a\)\1bc*d    b       aabcd   aabcd
+\(a\)\1bc*d    b       aabd    aabd
+\(a\)\1bc*d    b       aabcccd aabcccd
+\(a\)\1bc*[ce]d        b       aabcccd aabcccd
+^\(a\)\1b\(c\)*cd$     b       aabcccd aabcccd
+
+# ordinary repetitions
+ab*c           &       abc     abc
+ab+c           -       abc     abc
+ab?c           -       abc     abc
+a\(*\)b                b       a*b     a*b
+a\(**\)b       b       ab      ab
+a\(***\)b      bC      BADRPT
+*a             b       *a      *a
+**a            b       a       a
+***a           bC      BADRPT
+
+# the dreaded bounded repetitions
+{              &       {       {
+{abc           &       {abc    {abc
+{1             C       BADRPT
+{1}            C       BADRPT
+a{b            &       a{b     a{b
+a{1}b          -       ab      ab
+a\{1\}b                b       ab      ab
+a{1,}b         -       ab      ab
+a\{1,\}b       b       ab      ab
+a{1,2}b                -       aab     aab
+a\{1,2\}b      b       aab     aab
+a{1            C       EBRACE
+a\{1           bC      EBRACE
+a{1a           C       EBRACE
+a\{1a          bC      EBRACE
+a{1a}          C       BADBR
+a\{1a\}                bC      BADBR
+a{,2}          -       a{,2}   a{,2}
+a\{,2\}                bC      BADBR
+a{,}           -       a{,}    a{,}
+a\{,\}         bC      BADBR
+a{1,x}         C       BADBR
+a\{1,x\}       bC      BADBR
+a{1,x          C       EBRACE
+a\{1,x         bC      EBRACE
+a{300}         C       BADBR
+a\{300\}       bC      BADBR
+a{1,0}         C       BADBR
+a\{1,0\}       bC      BADBR
+ab{0,0}c       -       abcac   ac
+ab\{0,0\}c     b       abcac   ac
+ab{0,1}c       -       abcac   abc
+ab\{0,1\}c     b       abcac   abc
+ab{0,3}c       -       abbcac  abbc
+ab\{0,3\}c     b       abbcac  abbc
+ab{1,1}c       -       acabc   abc
+ab\{1,1\}c     b       acabc   abc
+ab{1,3}c       -       acabc   abc
+ab\{1,3\}c     b       acabc   abc
+ab{2,2}c       -       abcabbc abbc
+ab\{2,2\}c     b       abcabbc abbc
+ab{2,4}c       -       abcabbc abbc
+ab\{2,4\}c     b       abcabbc abbc
+((a{1,10}){1,10}){1,10}        -       a       a       a,a
+
+# multiple repetitions
+a**            &C      BADRPT
+a++            C       BADRPT
+a??            C       BADRPT
+a*+            C       BADRPT
+a*?            C       BADRPT
+a+*            C       BADRPT
+a+?            C       BADRPT
+a?*            C       BADRPT
+a?+            C       BADRPT
+a{1}{1}                C       BADRPT
+a*{1}          C       BADRPT
+a+{1}          C       BADRPT
+a?{1}          C       BADRPT
+a{1}*          C       BADRPT
+a{1}+          C       BADRPT
+a{1}?          C       BADRPT
+a*{b}          -       a{b}    a{b}
+a\{1\}\{1\}    bC      BADRPT
+a*\{1\}                bC      BADRPT
+a\{1\}*                bC      BADRPT
+
+# brackets, and numerous perversions thereof
+a[b]c          &       abc     abc
+a[ab]c         &       abc     abc
+a[^ab]c                &       adc     adc
+a[]b]c         &       a]c     a]c
+a[[b]c         &       a[c     a[c
+a[-b]c         &       a-c     a-c
+a[^]b]c                &       adc     adc
+a[^-b]c                &       adc     adc
+a[b-]c         &       a-c     a-c
+a[b            &C      EBRACK
+a[]            &C      EBRACK
+a[1-3]c                &       a2c     a2c
+a[3-1]c                &C      ERANGE
+a[1-3-5]c      &C      ERANGE
+a[[.-.]--]c    &       a-c     a-c
+a[1-           &C      ERANGE
+a[[.           &C      EBRACK
+a[[.x          &C      EBRACK
+a[[.x.         &C      EBRACK
+a[[.x.]                &C      EBRACK
+a[[.x.]]       &       ax      ax
+a[[.x,.]]      &C      ECOLLATE
+a[[.one.]]b    &       a1b     a1b
+a[[.notdef.]]b &C      ECOLLATE
+a[[.].]]b      &       a]b     a]b
+a[[:alpha:]]c  &       abc     abc
+a[[:notdef:]]c &C      ECTYPE
+a[[:           &C      EBRACK
+a[[:alpha      &C      EBRACK
+a[[:alpha:]    &C      EBRACK
+a[[:alpha,:]   &C      ECTYPE
+a[[:]:]]b      &C      ECTYPE
+a[[:-:]]b      &C      ECTYPE
+a[[:alph:]]    &C      ECTYPE
+a[[:alphabet:]]        &C      ECTYPE
+[[:alnum:]]+   -       -%@a0X- a0X
+[[:alpha:]]+   -       -%@aX0- aX
+[[:blank:]]+   -       aSSTb   SST
+[[:cntrl:]]+   -       aNTb    NT
+[[:digit:]]+   -       a019b   019
+[[:graph:]]+   -       Sa%bS   a%b
+[[:lower:]]+   -       AabC    ab
+[[:print:]]+   -       NaSbN   aSb
+[[:punct:]]+   -       S%-&T   %-&
+[[:space:]]+   -       aSNTb   SNT
+[[:upper:]]+   -       aBCd    BC
+[[:xdigit:]]+  -       p0f3Cq  0f3C
+a[[=b=]]c      &       abc     abc
+a[[=           &C      EBRACK
+a[[=b          &C      EBRACK
+a[[=b=         &C      EBRACK
+a[[=b=]                &C      EBRACK
+a[[=b,=]]      &C      ECOLLATE
+a[[=one=]]b    &       a1b     a1b
+
+# complexities
+a(((b)))c      -       abc     abc
+a(b|(c))d      -       abd     abd
+a(b*|c)d       -       abbd    abbd
+# just gotta have one DFA-buster, of course
+a[ab]{20}      -       aaaaabaaaabaaaabaaaab   aaaaabaaaabaaaabaaaab
+# and an inline expansion in case somebody gets tricky
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab]      -       aaaaabaaaabaaaabaaaab   aaaaabaaaabaaaabaaaab
+# and in case somebody just slips in an NFA...
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night)     -       aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights
+# fish for anomalies as the number of states passes 32
+12345678901234567890123456789  -       a12345678901234567890123456789b 12345678901234567890123456789
+123456789012345678901234567890 -       a123456789012345678901234567890b        123456789012345678901234567890
+1234567890123456789012345678901        -       a1234567890123456789012345678901b       1234567890123456789012345678901
+12345678901234567890123456789012       -       a12345678901234567890123456789012b      12345678901234567890123456789012
+123456789012345678901234567890123      -       a123456789012345678901234567890123b     123456789012345678901234567890123
+# and one really big one, beyond any plausible word width
+1234567890123456789012345678901234567890123456789012345678901234567890 -       a1234567890123456789012345678901234567890123456789012345678901234567890b        1234567890123456789012345678901234567890123456789012345678901234567890
+# fish for problems as brackets go past 8
+[ab][cd][ef][gh][ij][kl][mn]   -       xacegikmoq      acegikm
+[ab][cd][ef][gh][ij][kl][mn][op]       -       xacegikmoq      acegikmo
+[ab][cd][ef][gh][ij][kl][mn][op][qr]   -       xacegikmoqy     acegikmoq
+[ab][cd][ef][gh][ij][kl][mn][op][q]    -       xacegikmoqy     acegikmoq
+
+# subtleties of matching
+abc            &       xabcy   abc
+a\(b\)?c\1d    b       acd
+aBc            i       Abc     Abc
+a[Bc]*d                i       abBCcd  abBCcd
+0[[:upper:]]1  &i      0a1     0a1
+0[[:lower:]]1  &i      0A1     0A1
+a[^b]c         &i      abc
+a[^b]c         &i      aBc
+a[^b]c         &i      adc     adc
+[a]b[c]                -       abc     abc
+[a]b[a]                -       aba     aba
+[abc]b[abc]    -       abc     abc
+[abc]b[abd]    -       abd     abd
+a(b?c)+d       -       accd    accd
+(wee|week)(knights|night)      -       weeknights      weeknights
+(we|wee|week|frob)(knights|night|day)  -       weeknights      weeknights
+a[bc]d         -       xyzaaabcaababdacd       abd
+a[ab]c         -       aaabc   abc
+abc            s       abc     abc
+a*             &       b       @b
+
+# Let's have some fun -- try to match a C comment.
+# first the obvious, which looks okay at first glance...
+/\*.*\*/       -       /*x*/   /*x*/
+# but...
+/\*.*\*/       -       /*x*/y/*z*/     /*x*/y/*z*/
+# okay, we must not match */ inside; try to do that...
+/\*([^*]|\*[^/])*\*/   -       /*x*/   /*x*/
+/\*([^*]|\*[^/])*\*/   -       /*x*/y/*z*/     /*x*/
+# but...
+/\*([^*]|\*[^/])*\*/   -       /*x**/y/*z*/    /*x**/y/*z*/
+# and a still fancier version, which does it right (I think)...
+/\*([^*]|\*+[^*/])*\*+/        -       /*x*/   /*x*/
+/\*([^*]|\*+[^*/])*\*+/        -       /*x*/y/*z*/     /*x*/
+/\*([^*]|\*+[^*/])*\*+/        -       /*x**/y/*z*/    /*x**/
+/\*([^*]|\*+[^*/])*\*+/        -       /*x****/y/*z*/  /*x****/
+/\*([^*]|\*+[^*/])*\*+/        -       /*x**x*/y/*z*/  /*x**x*/
+/\*([^*]|\*+[^*/])*\*+/        -       /*x***x/y/*z*/  /*x***x/y/*z*/
+
+# subexpressions
+.*             -       abc     abc     -
+a(b)(c)d       -       abcd    abcd    b,c
+a(((b)))c      -       abc     abc     b,b,b
+a(b|(c))d      -       abd     abd     b,-
+a(b*|c|e)d     -       abbd    abbd    bb
+a(b*|c|e)d     -       acd     acd     c
+a(b*|c|e)d     -       ad      ad      @d
+a(b?)c         -       abc     abc     b
+a(b?)c         -       ac      ac      @c
+a(b+)c         -       abc     abc     b
+a(b+)c         -       abbbc   abbbc   bbb
+a(b*)c         -       ac      ac      @c
+(a|ab)(bc([de]+)f|cde) -       abcdef  abcdef  a,bcdef,de
+# the regression tester only asks for 9 subexpressions
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)k  -       abcdefghijk     abcdefghijk     b,c,d,e,f,g,h,i,j
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l       -       abcdefghijkl    abcdefghijkl    b,c,d,e,f,g,h,i,j,k
+a([bc]?)c      -       abc     abc     b
+a([bc]?)c      -       ac      ac      @c
+a([bc]+)c      -       abc     abc     b
+a([bc]+)c      -       abcc    abcc    bc
+a([bc]+)bc     -       abcbc   abcbc   bc
+a(bb+|b)b      -       abb     abb     b
+a(bbb+|bb+|b)b -       abb     abb     b
+a(bbb+|bb+|b)b -       abbb    abbb    bb
+a(bbb+|bb+|b)bb        -       abbb    abbb    b
+(.*).*         -       abcdef  abcdef  abcdef
+(a*)*          -       bc      @b      @b
+
+# do we get the right subexpression when it is used more than once?
+a(b|c)*d       -       ad      ad      -
+a(b|c)*d       -       abcd    abcd    c
+a(b|c)+d       -       abd     abd     b
+a(b|c)+d       -       abcd    abcd    c
+a(b|c?)+d      -       ad      ad      @d
+a(b|c?)+d      -       abcd    abcd    @d
+a(b|c){0,0}d   -       ad      ad      -
+a(b|c){0,1}d   -       ad      ad      -
+a(b|c){0,1}d   -       abd     abd     b
+a(b|c){0,2}d   -       ad      ad      -
+a(b|c){0,2}d   -       abcd    abcd    c
+a(b|c){0,}d    -       ad      ad      -
+a(b|c){0,}d    -       abcd    abcd    c
+a(b|c){1,1}d   -       abd     abd     b
+a(b|c){1,1}d   -       acd     acd     c
+a(b|c){1,2}d   -       abd     abd     b
+a(b|c){1,2}d   -       abcd    abcd    c
+a(b|c){1,}d    -       abd     abd     b
+a(b|c){1,}d    -       abcd    abcd    c
+a(b|c){2,2}d   -       acbd    acbd    b
+a(b|c){2,2}d   -       abcd    abcd    c
+a(b|c){2,4}d   -       abcd    abcd    c
+a(b|c){2,4}d   -       abcbd   abcbd   b
+a(b|c){2,4}d   -       abcbcd  abcbcd  c
+a(b|c){2,}d    -       abcd    abcd    c
+a(b|c){2,}d    -       abcbd   abcbd   b
+a(b+|((c)*))+d -       abd     abd     @d,@d,-
+a(b+|((c)*))+d -       abcd    abcd    @d,@d,-
+
+# check out the STARTEND option
+[abc]          &#      a(b)c   b
+[abc]          &#      a(d)c
+[abc]          &#      a(bc)d  b
+[abc]          &#      a(dc)d  c
+.              &#      a()c
+b.*c           &#      b(bc)c  bc
+b.*            &#      b(bc)c  bc
+.*c            &#      b(bc)c  bc
+
+# plain strings, with the NOSPEC flag
+abc            m       abc     abc
+abc            m       xabcy   abc
+abc            m       xyz
+a*b            m       aba*b   a*b
+a*b            m       ab
+""             mC      EMPTY
+
+# cases involving NULs
+aZb            &       a       a
+aZb            &p      a
+aZb            &p#     (aZb)   aZb
+aZ*b           &p#     (ab)    ab
+a.b            &#      (aZb)   aZb
+a.*            &#      (aZb)c  aZb
+
+# word boundaries (ick)
+[[:<:]]a       &       a       a
+[[:<:]]a       &       ba
+[[:<:]]a       &       -a      a
+a[[:>:]]       &       a       a
+a[[:>:]]       &       ab
+a[[:>:]]       &       a-      a
+[[:<:]]a.c[[:>:]]      &       axcd-dayc-dazce-abc     abc
+[[:<:]]a.c[[:>:]]      &       axcd-dayc-dazce-abc-q   abc
+[[:<:]]a.c[[:>:]]      &       axc-dayc-dazce-abc      axc
+[[:<:]]b.c[[:>:]]      &       a_bxc-byc_d-bzc-q       bzc
+[[:<:]].x..[[:>:]]     &       y_xa_-_xb_y-_xc_-axdc   _xc_
+[[:<:]]a_b[[:>:]]      &       x_a_b
+
+# past problems, and suspected problems
+(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A])  -       A1      A1
+abcdefghijklmnop       i       abcdefghijklmnop        abcdefghijklmnop
+abcdefghijklmnopqrstuv i       abcdefghijklmnopqrstuv  abcdefghijklmnopqrstuv
+(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN])    -       CC11    CC11
+CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a   -       CC11    CC11
+Char \([a-z0-9_]*\)\[.*        b       Char xyz[k      Char xyz[k      xyz
+a?b    -       ab      ab
+-\{0,1\}[0-9]*$        b       -5      -5
diff --git a/regex-src/utils.h b/regex-src/utils.h
new file mode 100644 (file)
index 0000000..1a997ac
--- /dev/null
@@ -0,0 +1,22 @@
+/* utility definitions */
+#ifdef _POSIX2_RE_DUP_MAX
+#define        DUPMAX  _POSIX2_RE_DUP_MAX
+#else
+#define        DUPMAX  255
+#endif
+#define        INFINITY        (DUPMAX + 1)
+#define        NC              (CHAR_MAX - CHAR_MIN + 1)
+typedef unsigned char uch;
+
+/* switch off assertions (if not already off) if no REDEBUG */
+#ifndef REDEBUG
+#ifndef NDEBUG
+#define        NDEBUG  /* no assertions please */
+#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
diff --git a/restore-src/Makefile.am b/restore-src/Makefile.am
new file mode 100644 (file)
index 0000000..c688629
--- /dev/null
@@ -0,0 +1,44 @@
+# Makefile for Amanda restore programs.
+
+INCLUDES =             -I$(top_srcdir)/common-src -I$(top_srcdir)/tape-src -I$(top_srcdir)/server-src
+
+LIB_EXTENSION = la
+
+sbin_PROGRAMS =        amrestore
+
+libexec_PROGRAMS =     amidxtaped
+
+###
+# 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) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+amidxtaped_SOURCES =   amidxtaped.c
+amidxtaped_LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+                   ../server-src/libamserver.$(LIB_EXTENSION) \
+                   ../tape-src/libamtape.$(LIB_EXTENSION) \
+                   ../common-src/libamanda.$(LIB_EXTENSION)
+
+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; \
+       done
+       @list="$(libexec_PROGRAMS)"; \
+       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
diff --git a/restore-src/Makefile.in b/restore-src/Makefile.in
new file mode 100644 (file)
index 0000000..ed42042
--- /dev/null
@@ -0,0 +1,628 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 restore programs.
+
+SOURCES = $(amidxtaped_SOURCES) amrestore.c
+
+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 = :
+host_triplet = @host@
+sbin_PROGRAMS = amrestore$(EXEEXT)
+libexec_PROGRAMS = amidxtaped$(EXEEXT)
+subdir = restore-src
+DIST_COMMON = $(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__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)"
+libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
+am_amidxtaped_OBJECTS = amidxtaped.$(OBJEXT)
+amidxtaped_OBJECTS = $(am_amidxtaped_OBJECTS)
+amidxtaped_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       ../server-src/libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amrestore_SOURCES = amrestore.c
+amrestore_OBJECTS = amrestore.$(OBJEXT)
+amrestore_LDADD = $(LDADD)
+amrestore_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(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
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/amidxtaped.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amrestore.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(amidxtaped_SOURCES) amrestore.c
+DIST_SOURCES = $(amidxtaped_SOURCES) amrestore.c
+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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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_srcdir)/common-src -I$(top_srcdir)/tape-src -I$(top_srcdir)/server-src
+LIB_EXTENSION = la
+
+###
+# 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) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+amidxtaped_SOURCES = amidxtaped.c
+amidxtaped_LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+                   ../server-src/libamserver.$(LIB_EXTENSION) \
+                   ../tape-src/libamtape.$(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  restore-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  restore-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-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
+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
+amidxtaped$(EXEEXT): $(amidxtaped_OBJECTS) $(amidxtaped_DEPENDENCIES) 
+       @rm -f amidxtaped$(EXEEXT)
+       $(LINK) $(amidxtaped_LDFLAGS) $(amidxtaped_OBJECTS) $(amidxtaped_LDADD) $(LIBS)
+amrestore$(EXEEXT): $(amrestore_OBJECTS) $(amrestore_DEPENDENCIES) 
+       @rm -f amrestore$(EXEEXT)
+       $(LINK) $(amrestore_LDFLAGS) $(amrestore_OBJECTS) $(amrestore_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amidxtaped.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amrestore.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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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 -z "$$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)
+installdirs:
+       for dir in "$(DESTDIR)$(libexecdir)" "$(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:
+       -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-libexecPROGRAMS 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-libexecPROGRAMS 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-libexecPROGRAMS \
+       uninstall-sbinPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libexecPROGRAMS 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-info \
+       install-info-am install-libexecPROGRAMS 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-libexecPROGRAMS uninstall-sbinPROGRAMS
+
+
+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; \
+       done
+       @list="$(libexec_PROGRAMS)"; \
+       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
+# 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/restore-src/amidxtaped.c b/restore-src/amidxtaped.c
new file mode 100644 (file)
index 0000000..9f9e62a
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * 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: amidxtaped.c,v 1.25.2.3.4.1.2.11 2004/01/29 19:26:51 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
+ * arguments from stdin (it is invoked via inet), one per line,
+ * preceeded by the number of them, and forms them into an argv
+ * structure, then execs amrestore
+ */
+
+#include "amanda.h"
+#include "clock.h"
+#include "version.h"
+
+#include "changer.h"
+#include "tapeio.h"
+#include "conffile.h"
+#include "logfile.h"
+
+static char *pgm = "amidxtaped";       /* in case argv[0] is not set */
+
+char *conf_logdir = NULL;
+char *conf_logfile = NULL;
+int get_lock = 0;
+char *found_device = NULL;
+
+static char *get_client_line P((void));
+
+/* get a line from client - line terminated by \r\n */
+static char *
+get_client_line()
+{
+    static char *line = NULL;
+    char *part = NULL;
+    int len;
+
+    amfree(line);
+    while(1) {
+       if((part = agets(stdin)) == NULL) {
+           if(errno != 0) {
+               dbprintf(("%s: read error: %s\n",
+                         debug_prefix_time(NULL), strerror(errno)));
+           } else {
+               dbprintf(("%s: EOF reached\n", debug_prefix_time(NULL)));
+           }
+           if(line) {
+               dbprintf(("%s: unprocessed input:\n", debug_prefix_time(NULL)));
+               dbprintf(("-----\n"));
+               dbprintf(("%s\n", line));
+               dbprintf(("-----\n"));
+           }
+           amfree(line);
+           amfree(part);
+           if(get_lock) {
+               unlink(conf_logfile);
+           }
+           dbclose();
+           exit(1);
+           /* NOTREACHED */
+       }
+       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';         /* zap the '\r' */
+           break;
+       }
+       /*
+        * Hmmm.  We got a "line" from agets(), 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");
+    }
+    dbprintf(("%s: > %s\n", debug_prefix_time(NULL), line));
+    return line;
+}
+
+int found = 0;
+char *searchlabel = NULL;
+int nslots, backwards;
+
+int scan_init(rc, ns, bk)
+int rc, ns, bk;
+{
+    if(rc) {
+       if(get_lock) {
+           unlink(conf_logfile);
+       }
+        error("could not get changer info: %s", changer_resultstr);
+    }
+    nslots = ns;
+    backwards = bk;
+
+    return 0;
+}
+
+
+int taperscan_slot(rc, slotstr, device)
+int rc;
+char *slotstr;
+char *device;
+{
+    char *errstr;
+    char *datestamp = NULL, *label = NULL;
+
+    if(rc == 2) {
+       dbprintf(("%s: fatal slot %s: %s\n", debug_prefix_time(NULL),
+                 slotstr, changer_resultstr));
+        return 1;
+    }
+    else if(rc == 1) {
+       dbprintf(("%s: slot %s: %s\n", debug_prefix_time(NULL),
+                 slotstr, changer_resultstr));
+        return 0;
+    }
+    else {
+        if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
+           dbprintf(("%s: slot %s: %s\n", debug_prefix_time(NULL),
+                     slotstr, errstr));
+        } else {
+            /* got an amanda tape */
+           dbprintf(("%s: slot %s: date %-8s label %s",
+                     debug_prefix_time(NULL), slotstr, datestamp, label));
+            if(strcmp(label, FAKE_LABEL) == 0 ||
+               strcmp(label, searchlabel) == 0) {
+                /* it's the one we are looking for, stop here */
+               found_device = newstralloc(found_device,device);
+               dbprintf((" (exact label match)\n"));
+                found = 1;
+                return 1;
+            }
+            else {
+               dbprintf((" (no match)\n"));
+            }
+        }
+    }
+    return 0;
+}
+
+
+int lock_logfile()
+{
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+        conf_logdir = stralloc(conf_logdir);
+    } else {
+        conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    conf_logfile = vstralloc(conf_logdir, "/log", NULL);
+    if (access(conf_logfile, F_OK) == 0) {
+        error("%s exists: amdump or amflush is already running, or you must run amcleanup", conf_logfile);
+    }
+    log_add(L_INFO, "amidxtaped");
+    return 1;
+}
+
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    int amrestore_nargs;
+    char **amrestore_args;
+    char *buf = NULL;
+    int i;
+    char *amrestore_path;
+    pid_t pid;
+    int isafile;
+    struct stat stat_tape;
+    char *tapename = NULL;
+    int fd;
+    char *s, *fp;
+    int ch;
+    char *errstr = NULL;
+    struct sockaddr_in addr;
+    amwait_t status;
+
+    int re_header = 0;
+    int re_end = 0;
+    char *re_label = NULL;
+    char *re_fsf = NULL;
+    char *re_device = NULL;
+    char *re_host = NULL;
+    char *re_disk = NULL;
+    char *re_datestamp = NULL;
+    char *re_config = NULL;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    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 (argc >= 1 && argv != NULL && argv[0] != NULL) {
+       if((pgm = strrchr(argv[0], '/')) != NULL) {
+           pgm++;
+       } else {
+           pgm = argv[0];
+       }
+    }
+
+    set_pname(pgm);
+
+#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);
+       setuid(client_uid);
+    }
+
+#endif /* FORCE_USERID */
+
+    /* initialize */
+    /* close stderr first so that debug file becomes it - amrestore
+       chats to stderr, which we don't want going to client */
+    /* if no debug file, ship to bit bucket */
+    (void)close(STDERR_FILENO);
+    dbopen();
+    startclock();
+    dbprintf(("%s: version %s\n", pgm, version()));
+#ifdef DEBUG_CODE
+    if(dbfd() != -1 && dbfd() != STDERR_FILENO)
+    {
+       if(dup2(dbfd(),STDERR_FILENO) != STDERR_FILENO)
+       {
+           perror("amidxtaped can't redirect stderr to the debug file");
+           dbprintf(("%s: can't redirect stderr to the debug file\n",
+                     debug_prefix_time(NULL)));
+           return 1;
+       }
+    }
+#else
+    if ((i = open("/dev/null", O_WRONLY)) == -1 ||
+       (i != STDERR_FILENO &&
+        (dup2(i, STDERR_FILENO) != STDERR_FILENO ||
+         close(i) != 0))) {
+       perror("amidxtaped can't redirect stderr");
+       return 1;
+    }
+#endif
+
+    if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) {
+       dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
+                 debug_prefix_time(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",
+             inet_ntoa(addr.sin_addr), addr.sin_family, htons(addr.sin_port));
+    }
+
+    /* do the security thing */
+    amfree(buf);
+    buf = stralloc(get_client_line());
+    s = buf;
+    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 (!security_ok(&addr, s-1, 0, &errstr)) {
+       error("security check failed: %s", errstr);
+    }
+
+    /* get the number of arguments */
+    amrestore_nargs = 0;
+    do {
+       amfree(buf);
+       buf = stralloc(get_client_line());
+       if(strncmp(buf, "LABEL=", 6) == 0) {
+           re_label = stralloc(buf+6);
+       }
+       else if(strncmp(buf, "FSF=", 4) == 0) {
+           int fsf = atoi(buf+4);
+           if(fsf > 0) {
+               re_fsf = stralloc(buf+4);
+           }
+       }
+       else if(strncmp(buf, "HEADER", 6) == 0) {
+           re_header = 1;
+       }
+       else if(strncmp(buf, "DEVICE=", 7) == 0) {
+           re_device = stralloc(buf+7);
+       }
+       else if(strncmp(buf, "HOST=", 5) == 0) {
+           re_host = stralloc(buf+5);
+       }
+       else if(strncmp(buf, "DISK=", 5) == 0) {
+           re_disk = stralloc(buf+5);
+       }
+       else if(strncmp(buf, "DATESTAMP=", 10) == 0) {
+           re_datestamp = stralloc(buf+10);
+       }
+       else if(strncmp(buf, "END", 3) == 0) {
+           re_end = 1;
+       }
+       else if(strncmp(buf, "CONFIG=", 7) == 0) {
+           re_config = stralloc(buf+7);
+       }
+       else if(buf[0] != '\0' && buf[0] >= '0' && buf[0] <= '9') {
+           amrestore_nargs = atoi(buf);
+           re_end = 1;
+       }
+       else {
+       }
+    } while (re_end == 0);
+
+    if(re_config) {
+       char *conffile;
+       config_dir = vstralloc(CONFIG_DIR, "/", re_config, "/", NULL);
+       conffile = stralloc2(config_dir, CONFFILE_NAME);
+       if (read_conffile(conffile)) {
+           dbprintf(("%s: config '%s' not found\n",
+                     debug_prefix_time(NULL), re_config));
+           amfree(re_fsf);
+           amfree(re_label);
+           amfree(re_config);
+       }
+    }
+    else {
+       amfree(re_fsf);
+       amfree(re_label);
+    }
+
+    if(re_device && re_config &&
+       strcmp(re_device, getconf_str(CNF_TAPEDEV)) == 0) {
+       get_lock = lock_logfile();
+    }
+
+    if(re_label && re_config &&
+       strcmp(re_device, getconf_str(CNF_AMRECOVER_CHANGER)) == 0) {
+
+       if(changer_init() == 0) {
+           dbprintf(("%s: No changer available\n",
+                      debug_prefix_time(NULL)));
+       }
+       else {
+           searchlabel = stralloc(re_label);
+           changer_find(scan_init, taperscan_slot, searchlabel);
+           if(found == 0) {
+               dbprintf(("%s: Can't find label \"%s\"\n",
+                         debug_prefix_time(NULL), searchlabel));
+               if(get_lock) {
+                   unlink(conf_logfile);
+               }
+               dbclose();
+               exit(1);
+           }
+           else {
+                    re_device=stralloc(found_device);
+               dbprintf(("%s: label \"%s\" found\n",
+                         debug_prefix_time(NULL), searchlabel));
+           }
+       }
+    }
+
+    if(re_fsf && re_config && getconf_int(CNF_AMRECOVER_DO_FSF) == 0) {
+       amfree(re_fsf);
+    }
+    if(re_label && re_config && getconf_int(CNF_AMRECOVER_CHECK_LABEL) == 0) {
+       amfree(re_label);
+    }
+
+    dbprintf(("%s: amrestore_nargs=%d\n",
+             debug_prefix_time(NULL),
+             amrestore_nargs));
+
+    amrestore_args = (char **)alloc((amrestore_nargs+12)*sizeof(char *));
+    i = 0;
+    amrestore_args[i++] = "amrestore";
+    if(re_header || re_device || re_host || re_disk || re_datestamp ||
+       re_label || re_fsf) {
+
+       amrestore_args[i++] = "-p";
+       if(re_header) amrestore_args[i++] = "-h";
+       if(re_label) {
+           amrestore_args[i++] = "-l";
+           amrestore_args[i++] = re_label;
+       }
+       if(re_fsf) {
+           amrestore_args[i++] = "-f";
+           amrestore_args[i++] = re_fsf;
+       }
+       if(re_device) amrestore_args[i++] = re_device;
+       if(re_host) amrestore_args[i++] = re_host;
+       if(re_disk) amrestore_args[i++] = re_disk;
+       if(re_datestamp) amrestore_args[i++] = re_datestamp;
+    }
+    else { /* fe_amidxtaped_nargs */
+       while (i <= amrestore_nargs) {
+           amrestore_args[i++] = stralloc(get_client_line());
+       }
+    }
+    amrestore_args[i] = NULL;
+
+    amrestore_path = vstralloc(sbindir, "/", "amrestore", NULL);
+
+    /* so got all the arguments, now ready to execv */
+    dbprintf(("%s: Ready to execv amrestore with:\n", debug_prefix_time(NULL)));
+    dbprintf(("path = %s\n", amrestore_path));
+    for (i = 0; amrestore_args[i] != NULL; i++)
+    {
+       dbprintf(("argv[%d] = \"%s\"\n", i, amrestore_args[i]));
+    }
+
+    if ((pid = fork()) == 0)
+    {
+       /* child */
+       (void)execv(amrestore_path, amrestore_args);
+
+       /* only get here if exec failed */
+       dbprintf(("%s: child could not exec %s: %s\n",
+                 debug_prefix_time(NULL),
+                 amrestore_path,
+                 strerror(errno)));
+       return 1;
+       /*NOT REACHED*/
+    }
+
+    /* this is the parent */
+    if (pid == -1)
+    {
+       dbprintf(("%s: error forking amrestore child: %s\n",
+                 debug_prefix_time(NULL), strerror(errno)));
+       if(get_lock) {
+           unlink(conf_logfile);
+       }
+       dbclose();
+       return 1;
+    }
+
+    /* wait for the child to do the restore */
+    if (waitpid(pid, &status, 0) == -1)
+    {
+       dbprintf(("%s: error waiting for amrestore child: %s\n",
+                 debug_prefix_time(NULL), strerror(errno)));
+       if(get_lock) {
+           unlink(conf_logfile);
+       }
+       dbclose();
+       return 1;
+    }
+    /* amrestore often sees the pipe reader (ie restore) quit in the middle
+       of the file because it has extracted all of the files needed. This
+       results in an exit status of 2. This unfortunately is the exit
+       status returned by many errors. Only when the exit status is 1 is it
+       guaranteed that an error existed. In all cases we should rewind the
+       tape if we can so that a retry starts from the correct place */
+    if (WIFEXITED(status) != 0)
+    {
+
+       dbprintf(("%s: amrestore terminated normally with status: %d\n",
+                 debug_prefix_time(NULL), WEXITSTATUS(status)));
+    }
+    else
+    {
+       dbprintf(("%s: amrestore terminated abnormally.\n",
+                 debug_prefix_time(NULL)));
+    }
+
+    /* rewind tape */
+    if(re_device) {
+       tapename = re_device;
+    }
+    else {
+       /* the first non-option argument is the tape device */
+       for (i = 1; i <= amrestore_nargs; i++)
+           if (amrestore_args[i][0] != '-')
+               break;
+       if (i > amrestore_nargs) {
+           dbprintf(("%s: Couldn't find tape in arguments\n",
+                     debug_prefix_time(NULL)));
+           if(get_lock) {
+               unlink(conf_logfile);
+           }
+           dbclose();
+           return 1;
+       }
+
+       tapename = stralloc(amrestore_args[i]);
+    }
+    if (tape_stat(tapename, &stat_tape) != 0) {
+        error("could not stat %s: %s", tapename, strerror(errno));
+    }
+    isafile = S_ISREG((stat_tape.st_mode));
+    if (!isafile) {
+       char *errstr = NULL;
+
+       dbprintf(("%s: rewinding tape ...\n", debug_prefix_time(NULL)));
+       errstr = tape_rewind(tapename);
+
+       if (errstr != NULL) {
+           dbprintf(("%s: %s\n", debug_prefix_time(NULL), errstr));
+           amfree(errstr);
+       } else {
+           dbprintf(("%s: done\n", debug_prefix_time(NULL)));
+       }
+    }
+
+    if(get_lock) {
+       unlink(conf_logfile);
+    }
+
+    amfree(tapename);
+    dbclose();
+    return 0;
+}
diff --git a/restore-src/amrestore.c b/restore-src/amrestore.c
new file mode 100644 (file)
index 0000000..e1161ba
--- /dev/null
@@ -0,0 +1,762 @@
+/*
+ * 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: amrestore.c,v 1.28.2.4.4.3.2.8 2003/02/09 04:33:13 jrjackson Exp $
+ *
+ * retrieves files from an amanda tape
+ */
+/*
+ * Pulls all files from the tape that match the hostname, diskname and
+ * datestamp regular expressions.
+ *
+ * If the header is output, only up to DISK_BLOCK_BYTES worth of it is
+ * sent, regardless of the tape blocksize.  This makes the disk image
+ * look like a holding disk image, and also makes it easier to remove
+ * the header (e.g. in amrecover) since it has a fixed size.
+ */
+
+#include "amanda.h"
+#include "tapeio.h"
+#include "fileheader.h"
+#include "util.h"
+
+#define CREAT_MODE     0640
+
+char *buffer = NULL;
+
+int compflag, rawflag, pipeflag, headerflag;
+int got_sigpipe, file_number;
+pid_t compress_pid = -1;
+char *compress_type = COMPRESS_FAST_OPT;
+int tapedev;
+int bytes_read;
+long blocksize = -1;
+long filefsf = -1;
+
+/* local functions */
+
+void errexit P((void));
+void handle_sigpipe P((int sig));
+int disk_match P((dumpfile_t *file, char *datestamp, 
+                 char *hostname, char *diskname));
+char *make_filename P((dumpfile_t *file));
+void read_file_header P((dumpfile_t *file, int isafile));
+static int get_block P((int isafile));
+void restore P((dumpfile_t *file, char *filename, int isafile));
+void usage P((void));
+int main P((int argc, char **argv));
+
+void errexit()
+/*
+ * Do exit(2) after an error, rather than exit(1).
+ */
+{
+    exit(2);
+}
+
+
+void handle_sigpipe(sig)
+int sig;
+/*
+ * Signal handler for the SIGPIPE signal.  Just sets a flag and returns.
+ * The act of catching the signal causes the pipe write() to fail with
+ * EINTR.
+ */
+{
+    got_sigpipe++;
+}
+
+int disk_match(file, datestamp, hostname, diskname)
+dumpfile_t *file;
+char *datestamp, *hostname, *diskname;
+
+/*
+ * 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.
+ */
+{
+    if(file->type != F_DUMPFILE) return 0;
+
+    if((*hostname == '\0' || match_host(hostname, file->name)) &&
+       (*diskname == '\0' || match_disk(diskname, file->disk)) &&
+       (*datestamp== '\0' || match_datestamp(datestamp, file->datestamp)))
+       return 1;
+    else
+       return 0;
+}
+
+
+char *make_filename(file)
+dumpfile_t *file;
+{
+    char number[NUM_STR_SIZE];
+    char *sfn;
+    char *fn;
+
+    ap_snprintf(number, sizeof(number), "%d", file->dumplevel);
+    sfn = sanitise_filename(file->disk);
+    fn = vstralloc(file->name,
+                  ".",
+                  sfn, 
+                  ".",
+                  file->datestamp,
+                  ".",
+                  number,
+                  NULL);
+    amfree(sfn);
+    return fn;
+}
+
+
+static int get_block(isafile)
+int isafile;
+{
+    static int test_blocksize = 1;
+    int buflen;
+
+    /*
+     * If this is the first call, set the blocksize if it was not on
+     * the command line.  Allocate the I/O buffer in any case.
+     *
+     * For files, the blocksize is always DISK_BLOCK_BYTES.  For tapes,
+     * we allocate a large buffer and set the size to the length of the
+     * first (successful) record.
+     */
+    buflen = blocksize;
+    if(test_blocksize) {
+       if(blocksize < 0) {
+           if(isafile) {
+               blocksize = buflen = DISK_BLOCK_BYTES;
+           } else {
+               buflen = MAX_TAPE_BLOCK_BYTES;
+           }
+       }
+       buffer = newalloc(buffer, buflen);
+    }
+    if(isafile) {
+       bytes_read = fullread(tapedev, buffer, buflen);
+    } else {
+       bytes_read = tapefd_read(tapedev, buffer, buflen);
+       if(blocksize < 0 && bytes_read > 0 && bytes_read < buflen) {
+           char *new_buffer;
+
+           blocksize = bytes_read;
+           new_buffer = alloc(blocksize);
+           memcpy(new_buffer, buffer, bytes_read);
+           amfree(buffer);
+           buffer = new_buffer;
+       }
+    }
+    if(blocksize > 0) {
+       test_blocksize = 0;
+    }
+    return bytes_read;
+}
+
+
+void read_file_header(file, isafile)
+dumpfile_t *file;
+int isafile;
+/*
+ * Reads the first block of a tape file.
+ */
+{
+    bytes_read = get_block(isafile);
+    if(bytes_read < 0) {
+       error("error reading file header: %s", strerror(errno));
+    } else if(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: %d byte%s\n",
+                   get_pname(), bytes_read, (bytes_read == 1) ? "" : "s");
+       }
+       file->type = F_UNKNOWN;
+    } else {
+       parse_file_header(buffer, file, bytes_read);
+    }
+    return;
+}
+
+
+void restore(file, filename, isafile)
+dumpfile_t *file;
+char *filename;
+int isafile;
+/*
+ * Restore the current file from tape.  Depending on the settings of
+ * the command line flags, the file might need to be compressed or
+ * uncompressed.  If so, a pipe through compress or uncompress is set
+ * up.  The final output usually goes to a file named host.disk.date.lev,
+ * but with the -p flag the output goes to stdout (and presumably is
+ * piped to restore).
+ */
+{
+    int rc = 0, dest, out, outpipe[2];
+    int wc;
+    int l, s;
+    int file_is_compressed;
+
+    /* adjust compression flag */
+
+    file_is_compressed = file->compressed;
+    if(!compflag && file_is_compressed && !known_compress_type(file)) {
+       fprintf(stderr, 
+               "%s: unknown compression suffix %s, can't uncompress\n",
+               get_pname(), file->comp_suffix);
+       compflag = 1;
+    }
+
+    /* set up final destination file */
+
+    if(pipeflag)
+       dest = 1;               /* standard output */
+    else {
+       char *filename_ext = NULL;
+
+       if(compflag) {
+           filename_ext = file_is_compressed ? file->comp_suffix
+                                             : COMPRESS_SUFFIX;
+       } else if(rawflag) {
+           filename_ext = ".RAW";
+       } else {
+           filename_ext = "";
+       }
+       filename_ext = stralloc2(filename, filename_ext);
+
+       if((dest = creat(filename, CREAT_MODE)) < 0)
+           error("could not create output file: %s", strerror(errno));
+       amfree(filename_ext);
+    }
+
+    out = dest;
+
+    /*
+     * If -r or -h, write the header before compress or uncompress pipe.
+     * Only write DISK_BLOCK_BYTES, regardless of how much was read.
+     * This makes the output look like a holding disk image, and also
+     * makes it easier to remove the header (e.g. in amrecover) since
+     * it has a fixed size.
+     */
+    if(rawflag || headerflag) {
+       int w;
+       char *cont_filename;
+
+       if(compflag && !file_is_compressed) {
+           file->compressed = 1;
+           ap_snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+                       " %s %s |", UNCOMPRESS_PATH,
+#ifdef UNCOMPRESS_OPT
+                       UNCOMPRESS_OPT
+#else
+                       ""
+#endif
+                       );
+           strncpy(file->comp_suffix,
+                   COMPRESS_SUFFIX,
+                   sizeof(file->comp_suffix)-1);
+           file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+       }
+
+       /* remove CONT_FILENAME from header */
+       cont_filename = stralloc(file->cont_filename);
+       memset(file->cont_filename,'\0',sizeof(file->cont_filename));
+       file->blocksize = DISK_BLOCK_BYTES;
+       build_header(buffer, file, bytes_read);
+
+       if((w = fullwrite(out, buffer, DISK_BLOCK_BYTES)) != DISK_BLOCK_BYTES) {
+           if(w < 0) {
+               error("write error: %s", strerror(errno));
+           } else {
+               error("write error: %d instead of %d", w, DISK_BLOCK_BYTES);
+           }
+       }
+       /* add CONT_FILENAME to header */
+       strncpy(file->cont_filename, cont_filename, sizeof(file->cont_filename));
+    }
+
+    /* if -c and file not compressed, insert compress pipe */
+
+    if(compflag && !file_is_compressed) {
+       if(pipe(outpipe) < 0) error("error [pipe: %s]", strerror(errno));
+       out = outpipe[1];
+       switch(compress_pid = fork()) {
+       case -1: error("could not fork for %s: %s",
+                      COMPRESS_PATH, strerror(errno));
+       default:
+           aclose(outpipe[0]);
+           aclose(dest);
+           break;
+       case 0:
+           aclose(outpipe[1]);
+           if(outpipe[0] != 0) {
+               if(dup2(outpipe[0], 0) == -1)
+                   error("error [dup2 pipe: %s]", strerror(errno));
+               aclose(outpipe[0]);
+           }
+           if(dest != 1) {
+               if(dup2(dest, 1) == -1)
+                   error("error [dup2 dest: %s]", strerror(errno));
+               aclose(dest);
+           }
+           if (*compress_type == '\0') {
+               compress_type = NULL;
+           }
+           execlp(COMPRESS_PATH, COMPRESS_PATH, compress_type, (char *)0);
+           error("could not exec %s: %s", COMPRESS_PATH, strerror(errno));
+       }
+    }
+
+    /* if not -r or -c, and file is compressed, insert uncompress pipe */
+
+    else if(!rawflag && !compflag && file_is_compressed) {
+       /* 
+        * XXX for now we know that for the two compression types we
+        * understand, .Z and optionally .gz, UNCOMPRESS_PATH will take
+        * care of both.  Later, we may need to reference a table of
+        * possible uncompress programs.
+        */
+       if(pipe(outpipe) < 0) error("error [pipe: %s]", strerror(errno));
+       out = outpipe[1];
+       switch(compress_pid = fork()) {
+       case -1: 
+           error("could not fork for %s: %s",
+                 UNCOMPRESS_PATH, strerror(errno));
+       default:
+           aclose(outpipe[0]);
+           aclose(dest);
+           break;
+       case 0:
+           aclose(outpipe[1]);
+           if(outpipe[0] != 0) {
+               if(dup2(outpipe[0], 0) < 0)
+                   error("dup2 pipe: %s", strerror(errno));
+               aclose(outpipe[0]);
+           }
+           if(dest != 1) {
+               if(dup2(dest, 1) < 0)
+                   error("dup2 dest: %s", strerror(errno));
+               aclose(dest);
+           }
+           (void) execlp(UNCOMPRESS_PATH, UNCOMPRESS_PATH,
+#ifdef UNCOMPRESS_OPT
+                         UNCOMPRESS_OPT,
+#endif
+                         (char *)0);
+           error("could not exec %s: %s", UNCOMPRESS_PATH, strerror(errno));
+       }
+    }
+
+
+    /* copy the rest of the file from tape to the output */
+    got_sigpipe = 0;
+    wc = 0;
+    do {
+       bytes_read = get_block(isafile);
+       if(bytes_read < 0) {
+           error("read error: %s", strerror(errno));
+       }
+       if(bytes_read == 0 && isafile) {
+           /*
+            * See if we need to switch to the next file.
+            */
+           if(file->cont_filename[0] == '\0') {
+               break;                          /* no more files */
+           }
+           close(tapedev);
+           if((tapedev = open(file->cont_filename, O_RDONLY)) == -1) {
+               char *cont_filename = strrchr(file->cont_filename,'/');
+               if(cont_filename) {
+                   cont_filename++;
+                   if((tapedev = open(cont_filename,O_RDONLY)) == -1) {
+                       error("can't open %s: %s", file->cont_filename,
+                             strerror(errno));
+                   }
+                   else {
+                       fprintf(stderr, "cannot open %s: %s\n",
+                               file->cont_filename, strerror(errno));
+                       fprintf(stderr, "using %s\n",
+                               cont_filename);
+                   }
+               }
+               else {
+                   error("can't open %s: %s", file->cont_filename,
+                         strerror(errno));
+               }
+           }
+           read_file_header(file, isafile);
+           if(file->type != F_DUMPFILE && file->type != F_CONT_DUMPFILE) {
+               fprintf(stderr, "unexpected header type: ");
+               print_header(stderr, file);
+               exit(2);
+           }
+           continue;
+       }
+       for(l = 0; l < bytes_read; l += s) {
+           if((s = write(out, buffer + l, bytes_read - l)) < 0) {
+               if(got_sigpipe) {
+                   fprintf(stderr,"Error %d (%s) offset %d+%d, wrote %d\n",
+                                  errno, strerror(errno), wc, bytes_read, rc);
+                   fprintf(stderr,  
+                           "%s: pipe reader has quit in middle of file.\n",
+                           get_pname());
+               } else {
+                   perror("amrestore: write error");
+               }
+               exit(2);
+           }
+       }
+       wc += bytes_read;
+    } while (bytes_read > 0);
+    if(pipeflag) {
+       if(out != dest) {
+           aclose(out);
+       }
+    } else {
+       aclose(out);
+    }
+}
+
+
+void usage()
+/*
+ * Print usage message and terminate.
+ */
+{
+    error("Usage: amrestore [-b blocksize] [-r|-c] [-p] [-h] [-f fileno] [-l label] tape-device|holdingfile [hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]]");
+}
+
+
+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.
+ */
+{
+    extern int optind;
+    int opt;
+    char *errstr;
+    int isafile;
+    struct stat stat_tape;
+    dumpfile_t file;
+    char *filename = NULL;
+    char *tapename = NULL;
+    struct match_list {
+       char *hostname;
+       char *diskname;
+       char *datestamp;
+       struct match_list *next;
+    } *match_list = NULL, *me = NULL;
+    int found_match;
+    int arg_state;
+    amwait_t compress_status;
+    int fd;
+    int r = 0;
+    char *e;
+    char *err;
+    char *label = NULL;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("amrestore");
+
+    erroutput_type = ERR_INTERACTIVE;
+
+    onerror(errexit);
+    signal(SIGPIPE, handle_sigpipe);
+
+    /* handle options */
+    while( (opt = getopt(argc, argv, "b:cCd:rpkhf:l:")) != -1) {
+       switch(opt) {
+       case 'b':
+           blocksize = strtol(optarg, &e, 10);
+           if(*e == 'k' || *e == 'K') {
+               blocksize *= 1024;
+           } else if(*e == 'm' || *e == 'M') {
+               blocksize *= 1024 * 1024;
+           } else if(*e != '\0') {
+               error("invalid blocksize value \"%s\"", optarg);
+           }
+           if(blocksize < DISK_BLOCK_BYTES) {
+               error("minimum block size is %dk", DISK_BLOCK_BYTES / 1024);
+           }
+           break;
+       case 'c': compflag = 1; break;
+       case 'C': compflag = 1; compress_type = COMPRESS_BEST_OPT; break;
+       case 'r': rawflag = 1; break;
+       case 'p': pipeflag = 1; break;
+       case 'h': headerflag = 1; break;
+       case 'f':
+           filefsf = strtol(optarg, &e, 10);
+           if(*e != '\0') {
+               error("invalid fileno value \"%s\"", optarg);
+           }
+           break;
+       case 'l':
+           label = stralloc(optarg);
+           break;
+       default:
+           usage();
+       }
+    }
+
+    if(compflag && rawflag) {
+       fprintf(stderr, 
+               "Cannot specify both -r (raw) and -c (compressed) output.\n");
+       usage();
+    }
+
+    if(optind >= argc) {
+       fprintf(stderr, "%s: Must specify tape-device or holdingfile\n",
+                       get_pname());
+       usage();
+    }
+
+    tapename = argv[optind++];
+
+#define ARG_GET_HOST 0
+#define ARG_GET_DISK 1
+#define ARG_GET_DATE 2
+
+    arg_state = ARG_GET_HOST;
+    while(optind < argc) {
+       switch(arg_state) {
+       case ARG_GET_HOST:
+           /*
+            * This is a new host/disk/date triple, so allocate a match_list.
+            */
+           me = alloc(sizeof(*me));
+           me->hostname = argv[optind++];
+           me->diskname = "";
+           me->datestamp = "";
+           me->next = match_list;
+           match_list = me;
+           if(me->hostname[0] != '\0'
+              && (errstr=validate_regexp(me->hostname)) != NULL) {
+               fprintf(stderr, "%s: bad hostname regex \"%s\": %s\n",
+                       get_pname(), me->hostname, errstr);
+               usage();
+           }
+           arg_state = ARG_GET_DISK;
+           break;
+       case ARG_GET_DISK:
+           me->diskname = 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();
+           }
+           arg_state = ARG_GET_DATE;
+           break;
+       case ARG_GET_DATE:
+           me->datestamp = 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();
+           }
+           arg_state = ARG_GET_HOST;
+           break;
+       }
+    }
+    if(match_list == NULL) {
+       match_list = alloc(sizeof(*match_list));
+       match_list->hostname = "";
+       match_list->diskname = "";
+       match_list->datestamp = "";
+       match_list->next = NULL;
+    }
+
+    if(tape_stat(tapename,&stat_tape)!=0) {
+       error("could not stat %s: %s", tapename, strerror(errno));
+    }
+    isafile=S_ISREG((stat_tape.st_mode));
+
+    if(label) {
+       if(isafile) {
+           fprintf(stderr,"%s: ignoring -l flag when restoring from a file.\n",
+                   get_pname());
+       }
+       else {
+           if((err = tape_rewind(tapename)) != NULL) {
+               error("Could not rewind device '%s': %s", tapename, err);
+           }
+           tapedev = tape_open(tapename, 0);
+           read_file_header(&file, isafile);
+           if(file.type != F_TAPESTART) {
+               fprintf(stderr,"Not an amanda tape\n");
+               exit (1);
+           }
+           if(strcmp(label, file.name) != 0) {
+               fprintf(stderr,"Wrong label: '%s'\n", file.name);
+               exit (1);
+           }
+           tapefd_close(tapedev);
+           if((err = tape_rewind(tapename)) != NULL) {
+               error("Could not rewind device '%s': %s", tapename, err);
+           }
+       }
+    }
+    file_number = 0;
+    if(filefsf != -1) {
+       if(isafile) {
+           fprintf(stderr,"%s: ignoring -f flag when restoring from a file.\n",
+                   get_pname());
+       }
+       else {
+           if((err = tape_rewind(tapename)) != NULL) {
+               error("Could not rewind device '%s': %s", tapename, err);
+           }
+           if((err = tape_fsf(tapename,filefsf)) != NULL) {
+               error("Could not fsf device '%s': %s", tapename, err);
+           }
+           file_number = filefsf;
+       }
+    }
+
+    if(isafile) {
+       tapedev = open(tapename, 0);
+    } else {
+       tapedev = tape_open(tapename, 0);
+    }
+    if(tapedev < 0) {
+       error("could not open %s: %s", tapename, strerror(errno));
+    }
+
+    read_file_header(&file, isafile);
+
+    if(file.type != F_TAPESTART && !isafile && filefsf == -1) {
+       fprintf(stderr, "%s: WARNING: not at start of tape, file numbers will be offset\n",
+                       get_pname());
+    }
+
+    while(file.type == F_TAPESTART || file.type == F_DUMPFILE) {
+       amfree(filename);
+       filename = make_filename(&file);
+       found_match = 0;
+       for(me = match_list; me; me = me->next) {
+           if(disk_match(&file,me->datestamp,me->hostname,me->diskname) != 0) {
+               found_match = 1;
+               break;
+           }
+       }
+       fprintf(stderr, "%s: %3d: %s ",
+                       get_pname(),
+                       file_number,
+                       found_match ? "restoring" : "skipping");
+       if(file.type != F_DUMPFILE) {
+           print_header(stderr, &file);
+       } else {
+           fprintf(stderr, "%s\n", filename);
+       }
+       if(found_match) {
+           restore(&file, filename, isafile);
+           if(compress_pid > 0) {
+               waitpid(compress_pid, &compress_status, 0);
+               compress_pid = -1;
+           }
+           if(pipeflag) {
+               file_number++;                  /* for the last message */
+               break;
+           }
+       }
+       if(isafile) {
+           break;
+       }
+       /*
+        * Note that at this point we know we are working with a tape,
+        * not a holding disk file, so we can call the tape functions
+        * without checking.
+        */
+       if(bytes_read == 0) {
+           /*
+            * If the last read got EOF, how to get to the next
+            * file depends on how the tape device driver is acting.
+            * If it is BSD-like, we do not really need to do anything.
+            * If it is Sys-V-like, we need to either fsf or close/open.
+            * The good news is, a close/open works in either case,
+            * so that's what we do.
+            */
+           tapefd_close(tapedev);
+           if((tapedev = tape_open(tapename, 0)) < 0) {
+               error("could not open %s: %s", tapename, strerror(errno));
+           }
+       } else {
+           /*
+            * 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) {
+               error("could not fsf %s: %s", tapename, strerror(errno));
+           }
+       }
+       file_number++;
+       read_file_header(&file, isafile);
+    }
+    if(isafile) {
+       close(tapedev);
+    } else {
+       /*
+        * See the notes above about advancing to the next file.
+        */
+       if(bytes_read == 0) {
+           tapefd_close(tapedev);
+           if((tapedev = tape_open(tapename, 0)) < 0) {
+               error("could not open %s: %s", tapename, strerror(errno));
+           }
+       } else {
+           if(tapefd_fsf(tapedev, 1) < 0) {
+               error("could not fsf %s: %s", tapename, strerror(errno));
+           }
+       }
+       tapefd_close(tapedev);
+    }
+
+    if((bytes_read <= 0 || file.type == F_TAPEEND) && !isafile) {
+       fprintf(stderr, "%s: %3d: reached ", get_pname(), file_number);
+       if(bytes_read <= 0) {
+           fprintf(stderr, "end of information\n");
+       } else {
+           print_header(stderr,&file);
+       }
+       r = 1;
+    }
+    return r;
+}
diff --git a/server-src/Makefile.am b/server-src/Makefile.am
new file mode 100644 (file)
index 0000000..84c9b06
--- /dev/null
@@ -0,0 +1,125 @@
+# Makefile for Amanda server programs.
+
+###
+# Yes, I really mean ../common-src.  The genversion.h file ends up getting
+# built there rather than into the source tree.
+###
+
+INCLUDES =             -I$(top_srcdir)/common-src \
+                       -I../common-src \
+                       -I$(top_srcdir)/tape-src
+
+lib_LTLIBRARIES =      libamserver.la
+LIB_EXTENSION = la
+
+sbin_PROGRAMS =                amadmin         amcheck         amflush         \
+                       amgetconf       amlabel         amtape          \
+                       amreport
+
+libexec_PROGRAMS =     amindexd        amlogroll       amtrmidx        \
+                       amtrmlog        driver          dumper          \
+                       planner         taper           amcleanupdisk
+
+sbin_SCRIPTS =         amcheckdb       amcleanup       amdump          \
+                       amoverview      amrmtape        amtoc           \
+                       amverify        amverifyrun     amstatus
+
+libamserver_la_SOURCES=        amindex.c       changer.c                       \
+                       conffile.c      diskfile.c      driverio.c      \
+                       holding.c       infofile.c      logfile.c       \
+                       tapefile.c      find.c          server_util.c
+
+libamserver_la_LDFLAGS= -release $(VERSION)
+
+###
+# 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) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+SUFFIXES =             .sh .pl
+
+.pl:
+                       cat $< > $@
+                       chmod a+x $@
+                       -test -z "$(PERL)" || $(PERL) -c $@
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+# there are used for testing only:
+TEST_PROGS = diskfile conffile infofile
+
+EXTRA_PROGRAMS = $(TEST_PROGS)
+
+EXTRA_DIST = dumper-krb4.c
+
+CLEANFILES = *.test.c
+
+amindexd_SOURCES =     amindexd.c                                      \
+                       disk_history.c                  disk_history.h  \
+                       list_dir.c                      list_dir.h
+
+amreport_SOURCES =     reporter.c
+
+amgetconf_SOURCES =    getconf.c
+
+noinst_HEADERS =       amindex.h       changer.h                       \
+                       conffile.h      diskfile.h      driverio.h      \
+                       holding.h       infofile.h      logfile.h       \
+                       tapefile.h      find.h          server_util.h
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS) $(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
+       @list="amcheck"; \
+       for p in $$list; do \
+               if echo "$(sbin_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
+                       pa=$(DESTDIR)$(sbindir)/`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
+       @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
+
+diskfile_SOURCES = diskfile.test.c
+conffile_SOURCES = conffile.test.c
+infofile_SOURCES = infofile.test.c
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
diff --git a/server-src/Makefile.in b/server-src/Makefile.in
new file mode 100644 (file)
index 0000000..ea0cd2a
--- /dev/null
@@ -0,0 +1,1028 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 server programs.
+
+###
+# Yes, I really mean ../common-src.  The genversion.h file ends up getting
+# built there rather than into the source tree.
+###
+
+
+
+
+SOURCES = $(libamserver_la_SOURCES) amadmin.c amcheck.c amcleanupdisk.c amflush.c $(amgetconf_SOURCES) $(amindexd_SOURCES) amlabel.c amlogroll.c $(amreport_SOURCES) amtape.c amtrmidx.c amtrmlog.c $(conffile_SOURCES) $(diskfile_SOURCES) driver.c dumper.c $(infofile_SOURCES) planner.c taper.c
+
+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 = :
+host_triplet = @host@
+sbin_PROGRAMS = amadmin$(EXEEXT) amcheck$(EXEEXT) amflush$(EXEEXT) \
+       amgetconf$(EXEEXT) amlabel$(EXEEXT) amtape$(EXEEXT) \
+       amreport$(EXEEXT)
+libexec_PROGRAMS = amindexd$(EXEEXT) amlogroll$(EXEEXT) \
+       amtrmidx$(EXEEXT) amtrmlog$(EXEEXT) driver$(EXEEXT) \
+       dumper$(EXEEXT) planner$(EXEEXT) taper$(EXEEXT) \
+       amcleanupdisk$(EXEEXT)
+EXTRA_PROGRAMS = $(am__EXEEXT_1)
+subdir = server-src
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(srcdir)/amcheckdb.sh.in \
+       $(srcdir)/amcleanup.sh.in $(srcdir)/amdump.sh.in \
+       $(srcdir)/amfreetapes.sh.in $(srcdir)/amoverview.pl.in \
+       $(srcdir)/amrmtape.sh.in $(srcdir)/amstatus.pl.in \
+       $(srcdir)/amtoc.pl.in $(srcdir)/amverify.sh.in \
+       $(srcdir)/amverifyrun.sh.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 = amcheckdb.sh amcleanup.sh amdump.sh \
+       amfreetapes.sh amoverview.pl amrmtape.sh amtoc.pl amverify.sh \
+       amstatus.pl amverifyrun.sh
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sbindir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libamserver_la_LIBADD =
+am_libamserver_la_OBJECTS = amindex.lo changer.lo conffile.lo \
+       diskfile.lo driverio.lo holding.lo infofile.lo logfile.lo \
+       tapefile.lo find.lo server_util.lo
+libamserver_la_OBJECTS = $(am_libamserver_la_OBJECTS)
+am__EXEEXT_1 = diskfile$(EXEEXT) conffile$(EXEEXT) infofile$(EXEEXT)
+libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
+amadmin_SOURCES = amadmin.c
+amadmin_OBJECTS = amadmin.$(OBJEXT)
+amadmin_LDADD = $(LDADD)
+amadmin_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amcheck_SOURCES = amcheck.c
+amcheck_OBJECTS = amcheck.$(OBJEXT)
+amcheck_LDADD = $(LDADD)
+amcheck_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amcleanupdisk_SOURCES = amcleanupdisk.c
+amcleanupdisk_OBJECTS = amcleanupdisk.$(OBJEXT)
+amcleanupdisk_LDADD = $(LDADD)
+amcleanupdisk_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amflush_SOURCES = amflush.c
+amflush_OBJECTS = amflush.$(OBJEXT)
+amflush_LDADD = $(LDADD)
+amflush_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_amgetconf_OBJECTS = getconf.$(OBJEXT)
+amgetconf_OBJECTS = $(am_amgetconf_OBJECTS)
+amgetconf_LDADD = $(LDADD)
+amgetconf_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_amindexd_OBJECTS = amindexd.$(OBJEXT) disk_history.$(OBJEXT) \
+       list_dir.$(OBJEXT)
+amindexd_OBJECTS = $(am_amindexd_OBJECTS)
+amindexd_LDADD = $(LDADD)
+amindexd_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amlabel_SOURCES = amlabel.c
+amlabel_OBJECTS = amlabel.$(OBJEXT)
+amlabel_LDADD = $(LDADD)
+amlabel_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amlogroll_SOURCES = amlogroll.c
+amlogroll_OBJECTS = amlogroll.$(OBJEXT)
+amlogroll_LDADD = $(LDADD)
+amlogroll_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_amreport_OBJECTS = reporter.$(OBJEXT)
+amreport_OBJECTS = $(am_amreport_OBJECTS)
+amreport_LDADD = $(LDADD)
+amreport_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amtape_SOURCES = amtape.c
+amtape_OBJECTS = amtape.$(OBJEXT)
+amtape_LDADD = $(LDADD)
+amtape_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amtrmidx_SOURCES = amtrmidx.c
+amtrmidx_OBJECTS = amtrmidx.$(OBJEXT)
+amtrmidx_LDADD = $(LDADD)
+amtrmidx_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+amtrmlog_SOURCES = amtrmlog.c
+amtrmlog_OBJECTS = amtrmlog.$(OBJEXT)
+amtrmlog_LDADD = $(LDADD)
+amtrmlog_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_conffile_OBJECTS = conffile.test.$(OBJEXT)
+conffile_OBJECTS = $(am_conffile_OBJECTS)
+conffile_LDADD = $(LDADD)
+conffile_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_diskfile_OBJECTS = diskfile.test.$(OBJEXT)
+diskfile_OBJECTS = $(am_diskfile_OBJECTS)
+diskfile_LDADD = $(LDADD)
+diskfile_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+driver_SOURCES = driver.c
+driver_OBJECTS = driver.$(OBJEXT)
+driver_LDADD = $(LDADD)
+driver_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+dumper_SOURCES = dumper.c
+dumper_OBJECTS = dumper.$(OBJEXT)
+dumper_LDADD = $(LDADD)
+dumper_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_infofile_OBJECTS = infofile.test.$(OBJEXT)
+infofile_OBJECTS = $(am_infofile_OBJECTS)
+infofile_LDADD = $(LDADD)
+infofile_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+planner_SOURCES = planner.c
+planner_OBJECTS = planner.$(OBJEXT)
+planner_LDADD = $(LDADD)
+planner_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+taper_SOURCES = taper.c
+taper_OBJECTS = taper.$(OBJEXT)
+taper_LDADD = $(LDADD)
+taper_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(sbin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/amadmin.Po ./$(DEPDIR)/amcheck.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amcleanupdisk.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amflush.Po ./$(DEPDIR)/amindex.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/amindexd.Po ./$(DEPDIR)/amlabel.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amlogroll.Po ./$(DEPDIR)/amtape.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amtrmidx.Po ./$(DEPDIR)/amtrmlog.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/changer.Plo ./$(DEPDIR)/conffile.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/conffile.test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/disk_history.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/diskfile.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/diskfile.test.Po ./$(DEPDIR)/driver.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/driverio.Plo ./$(DEPDIR)/dumper.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/find.Plo ./$(DEPDIR)/getconf.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/holding.Plo ./$(DEPDIR)/infofile.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/infofile.test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/list_dir.Po ./$(DEPDIR)/logfile.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/planner.Po ./$(DEPDIR)/reporter.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/server_util.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/tapefile.Plo ./$(DEPDIR)/taper.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libamserver_la_SOURCES) amadmin.c amcheck.c \
+       amcleanupdisk.c amflush.c $(amgetconf_SOURCES) \
+       $(amindexd_SOURCES) amlabel.c amlogroll.c $(amreport_SOURCES) \
+       amtape.c amtrmidx.c amtrmlog.c $(conffile_SOURCES) \
+       $(diskfile_SOURCES) driver.c dumper.c $(infofile_SOURCES) \
+       planner.c taper.c
+DIST_SOURCES = $(libamserver_la_SOURCES) amadmin.c amcheck.c \
+       amcleanupdisk.c amflush.c $(amgetconf_SOURCES) \
+       $(amindexd_SOURCES) amlabel.c amlogroll.c $(amreport_SOURCES) \
+       amtape.c amtrmidx.c amtrmlog.c $(conffile_SOURCES) \
+       $(diskfile_SOURCES) driver.c dumper.c $(infofile_SOURCES) \
+       planner.c taper.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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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_srcdir)/common-src \
+                       -I../common-src \
+                       -I$(top_srcdir)/tape-src
+
+lib_LTLIBRARIES = libamserver.la
+LIB_EXTENSION = la
+sbin_SCRIPTS = amcheckdb       amcleanup       amdump          \
+                       amoverview      amrmtape        amtoc           \
+                       amverify        amverifyrun     amstatus
+
+libamserver_la_SOURCES = amindex.c     changer.c                       \
+                       conffile.c      diskfile.c      driverio.c      \
+                       holding.c       infofile.c      logfile.c       \
+                       tapefile.c      find.c          server_util.c
+
+libamserver_la_LDFLAGS = -release $(VERSION)
+
+###
+# 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) \
+       libamserver.$(LIB_EXTENSION) \
+       ../tape-src/libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+SUFFIXES = .sh .pl
+
+# there are used for testing only:
+TEST_PROGS = diskfile conffile infofile
+EXTRA_DIST = dumper-krb4.c
+CLEANFILES = *.test.c
+amindexd_SOURCES = amindexd.c                                  \
+                       disk_history.c                  disk_history.h  \
+                       list_dir.c                      list_dir.h
+
+amreport_SOURCES = reporter.c
+amgetconf_SOURCES = getconf.c
+noinst_HEADERS = amindex.h     changer.h                       \
+                       conffile.h      diskfile.h      driverio.h      \
+                       holding.h       infofile.h      logfile.h       \
+                       tapefile.h      find.h          server_util.h
+
+diskfile_SOURCES = diskfile.test.c
+conffile_SOURCES = conffile.test.c
+infofile_SOURCES = infofile.test.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .sh .pl .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  server-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  server-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
+amcheckdb.sh: $(top_builddir)/config.status $(srcdir)/amcheckdb.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amcleanup.sh: $(top_builddir)/config.status $(srcdir)/amcleanup.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amdump.sh: $(top_builddir)/config.status $(srcdir)/amdump.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amfreetapes.sh: $(top_builddir)/config.status $(srcdir)/amfreetapes.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amoverview.pl: $(top_builddir)/config.status $(srcdir)/amoverview.pl.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amrmtape.sh: $(top_builddir)/config.status $(srcdir)/amrmtape.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amtoc.pl: $(top_builddir)/config.status $(srcdir)/amtoc.pl.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amverify.sh: $(top_builddir)/config.status $(srcdir)/amverify.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amstatus.pl: $(top_builddir)/config.status $(srcdir)/amstatus.pl.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+amverifyrun.sh: $(top_builddir)/config.status $(srcdir)/amverifyrun.sh.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+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="`echo $$p | sed -e 's|^.*/||'`"; \
+           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)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         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
+libamserver.la: $(libamserver_la_OBJECTS) $(libamserver_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(libamserver_la_LDFLAGS) $(libamserver_la_OBJECTS) $(libamserver_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
+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
+amadmin$(EXEEXT): $(amadmin_OBJECTS) $(amadmin_DEPENDENCIES) 
+       @rm -f amadmin$(EXEEXT)
+       $(LINK) $(amadmin_LDFLAGS) $(amadmin_OBJECTS) $(amadmin_LDADD) $(LIBS)
+amcheck$(EXEEXT): $(amcheck_OBJECTS) $(amcheck_DEPENDENCIES) 
+       @rm -f amcheck$(EXEEXT)
+       $(LINK) $(amcheck_LDFLAGS) $(amcheck_OBJECTS) $(amcheck_LDADD) $(LIBS)
+amcleanupdisk$(EXEEXT): $(amcleanupdisk_OBJECTS) $(amcleanupdisk_DEPENDENCIES) 
+       @rm -f amcleanupdisk$(EXEEXT)
+       $(LINK) $(amcleanupdisk_LDFLAGS) $(amcleanupdisk_OBJECTS) $(amcleanupdisk_LDADD) $(LIBS)
+amflush$(EXEEXT): $(amflush_OBJECTS) $(amflush_DEPENDENCIES) 
+       @rm -f amflush$(EXEEXT)
+       $(LINK) $(amflush_LDFLAGS) $(amflush_OBJECTS) $(amflush_LDADD) $(LIBS)
+amgetconf$(EXEEXT): $(amgetconf_OBJECTS) $(amgetconf_DEPENDENCIES) 
+       @rm -f amgetconf$(EXEEXT)
+       $(LINK) $(amgetconf_LDFLAGS) $(amgetconf_OBJECTS) $(amgetconf_LDADD) $(LIBS)
+amindexd$(EXEEXT): $(amindexd_OBJECTS) $(amindexd_DEPENDENCIES) 
+       @rm -f amindexd$(EXEEXT)
+       $(LINK) $(amindexd_LDFLAGS) $(amindexd_OBJECTS) $(amindexd_LDADD) $(LIBS)
+amlabel$(EXEEXT): $(amlabel_OBJECTS) $(amlabel_DEPENDENCIES) 
+       @rm -f amlabel$(EXEEXT)
+       $(LINK) $(amlabel_LDFLAGS) $(amlabel_OBJECTS) $(amlabel_LDADD) $(LIBS)
+amlogroll$(EXEEXT): $(amlogroll_OBJECTS) $(amlogroll_DEPENDENCIES) 
+       @rm -f amlogroll$(EXEEXT)
+       $(LINK) $(amlogroll_LDFLAGS) $(amlogroll_OBJECTS) $(amlogroll_LDADD) $(LIBS)
+amreport$(EXEEXT): $(amreport_OBJECTS) $(amreport_DEPENDENCIES) 
+       @rm -f amreport$(EXEEXT)
+       $(LINK) $(amreport_LDFLAGS) $(amreport_OBJECTS) $(amreport_LDADD) $(LIBS)
+amtape$(EXEEXT): $(amtape_OBJECTS) $(amtape_DEPENDENCIES) 
+       @rm -f amtape$(EXEEXT)
+       $(LINK) $(amtape_LDFLAGS) $(amtape_OBJECTS) $(amtape_LDADD) $(LIBS)
+amtrmidx$(EXEEXT): $(amtrmidx_OBJECTS) $(amtrmidx_DEPENDENCIES) 
+       @rm -f amtrmidx$(EXEEXT)
+       $(LINK) $(amtrmidx_LDFLAGS) $(amtrmidx_OBJECTS) $(amtrmidx_LDADD) $(LIBS)
+amtrmlog$(EXEEXT): $(amtrmlog_OBJECTS) $(amtrmlog_DEPENDENCIES) 
+       @rm -f amtrmlog$(EXEEXT)
+       $(LINK) $(amtrmlog_LDFLAGS) $(amtrmlog_OBJECTS) $(amtrmlog_LDADD) $(LIBS)
+conffile$(EXEEXT): $(conffile_OBJECTS) $(conffile_DEPENDENCIES) 
+       @rm -f conffile$(EXEEXT)
+       $(LINK) $(conffile_LDFLAGS) $(conffile_OBJECTS) $(conffile_LDADD) $(LIBS)
+diskfile$(EXEEXT): $(diskfile_OBJECTS) $(diskfile_DEPENDENCIES) 
+       @rm -f diskfile$(EXEEXT)
+       $(LINK) $(diskfile_LDFLAGS) $(diskfile_OBJECTS) $(diskfile_LDADD) $(LIBS)
+driver$(EXEEXT): $(driver_OBJECTS) $(driver_DEPENDENCIES) 
+       @rm -f driver$(EXEEXT)
+       $(LINK) $(driver_LDFLAGS) $(driver_OBJECTS) $(driver_LDADD) $(LIBS)
+dumper$(EXEEXT): $(dumper_OBJECTS) $(dumper_DEPENDENCIES) 
+       @rm -f dumper$(EXEEXT)
+       $(LINK) $(dumper_LDFLAGS) $(dumper_OBJECTS) $(dumper_LDADD) $(LIBS)
+infofile$(EXEEXT): $(infofile_OBJECTS) $(infofile_DEPENDENCIES) 
+       @rm -f infofile$(EXEEXT)
+       $(LINK) $(infofile_LDFLAGS) $(infofile_OBJECTS) $(infofile_LDADD) $(LIBS)
+planner$(EXEEXT): $(planner_OBJECTS) $(planner_DEPENDENCIES) 
+       @rm -f planner$(EXEEXT)
+       $(LINK) $(planner_LDFLAGS) $(planner_OBJECTS) $(planner_LDADD) $(LIBS)
+taper$(EXEEXT): $(taper_OBJECTS) $(taper_DEPENDENCIES) 
+       @rm -f taper$(EXEEXT)
+       $(LINK) $(taper_LDFLAGS) $(taper_OBJECTS) $(taper_LDADD) $(LIBS)
+install-sbinSCRIPTS: $(sbin_SCRIPTS)
+       @$(NORMAL_INSTALL)
+       test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+       @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         if test -f $$d$$p; then \
+           f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+           echo " $(sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+           $(sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \
+         else :; fi; \
+       done
+
+uninstall-sbinSCRIPTS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sbin_SCRIPTS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+         echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+         rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+       done
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amadmin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amcheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amcleanupdisk.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amflush.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amindex.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amindexd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amlabel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amlogroll.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amtape.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amtrmidx.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amtrmlog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/changer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conffile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conffile.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/disk_history.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskfile.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driverio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dumper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getconf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/holding.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infofile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infofile.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list_dir.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/planner.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reporter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tapefile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/taper.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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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 -z "$$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) $(SCRIPTS) $(HEADERS)
+installdirs:
+       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(sbindir)" "$(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:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -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 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-libLTLIBRARIES install-libexecPROGRAMS \
+       install-sbinPROGRAMS install-sbinSCRIPTS
+       @$(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 uninstall-sbinPROGRAMS \
+       uninstall-sbinSCRIPTS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libLTLIBRARIES clean-libexecPROGRAMS 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-info install-info-am install-libLTLIBRARIES \
+       install-libexecPROGRAMS install-man install-sbinPROGRAMS \
+       install-sbinSCRIPTS 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 uninstall-sbinPROGRAMS \
+       uninstall-sbinSCRIPTS
+
+
+.pl:
+                       cat $< > $@
+                       chmod a+x $@
+                       -test -z "$(PERL)" || $(PERL) -c $@
+
+.sh:
+                       cat $< > $@
+                       chmod a+x $@
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS) $(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
+       @list="amcheck"; \
+       for p in $$list; do \
+               if echo "$(sbin_PROGRAMS)" | grep $$p >/dev/null 2>&1; then \
+                       pa=$(DESTDIR)$(sbindir)/`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
+       @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
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
+# 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/server-src/amadmin.c b/server-src/amadmin.c
new file mode 100644 (file)
index 0000000..30b5fb5
--- /dev/null
@@ -0,0 +1,1606 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: amadmin.c,v 1.49.2.13.2.3.2.15 2003/11/18 16:44:34 martinea Exp $
+ *
+ * controlling process for the Amanda backup system
+ */
+#include "amanda.h"
+#include "conffile.h"
+#include "diskfile.h"
+#include "tapefile.h"
+#include "infofile.h"
+#include "logfile.h"
+#include "version.h"
+#include "holding.h"
+#include "find.h"
+
+disklist_t *diskqp;
+
+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((void));
+void bumpsize P((void));
+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));
+
+static char *conf_tapelist = NULL;
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    int fd;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    char *conf_diskfile;
+    char *conf_infofile;
+    char *conffile;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amadmin");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = ERR_INTERACTIVE;
+
+    if(argc < 3) usage();
+
+    if(strcmp(argv[2],"version") == 0) {
+       for(argc=0; version_info[argc]; printf("%s",version_info[argc++]));
+       return 0;
+    }
+    config_name = argv[1];
+    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);
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((diskqp = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist \"%s\"", conf_diskfile);
+    }
+    amfree(conf_diskfile);
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+    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)) {
+       error("could not open info db \"%s\"", conf_infofile);
+    }
+    amfree(conf_infofile);
+
+    if(strcmp(argv[2],"force-bump") == 0) force_bump(argc, argv);
+    else if(strcmp(argv[2],"force-no-bump") == 0) force_no_bump(argc, argv);
+    else if(strcmp(argv[2],"unforce-bump") == 0) unforce_bump(argc, argv);
+    else if(strcmp(argv[2],"force") == 0) force(argc, argv);
+    else if(strcmp(argv[2],"unforce") == 0) unforce(argc, argv);
+    else if(strcmp(argv[2],"reuse") == 0) reuse(argc, argv);
+    else if(strcmp(argv[2],"no-reuse") == 0) noreuse(argc, argv);
+    else if(strcmp(argv[2],"info") == 0) info(argc, argv);
+    else if(strcmp(argv[2],"due") == 0) due(argc, argv);
+    else if(strcmp(argv[2],"find") == 0) find(argc, argv);
+    else if(strcmp(argv[2],"delete") == 0) delete(argc, argv);
+    else if(strcmp(argv[2],"balance") == 0) balance(argc, argv);
+    else if(strcmp(argv[2],"tape") == 0) tape();
+    else if(strcmp(argv[2],"bumpsize") == 0) bumpsize();
+    else if(strcmp(argv[2],"import") == 0) import_db(argc, argv);
+    else if(strcmp(argv[2],"export") == 0) export_db(argc, argv);
+    else if(strcmp(argv[2],"disklist") == 0) disklist(argc, argv);
+    else {
+       fprintf(stderr, "%s: unknown command \"%s\"\n", argv[0], argv[2]);
+       usage();
+    }
+    close_infofile();
+    clear_tapelist();
+    amfree(conf_tapelist);
+    amfree(config_dir);
+
+    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 0;
+}
+
+
+void usage P((void))
+{
+    fprintf(stderr, "\nUsage: %s%s <conf> <command> {<args>} ...\n",
+           get_pname(), versionsuffix());
+    fprintf(stderr, "    Valid <command>s are:\n");
+    fprintf(stderr,"\tversion\t\t\t\t# Show version info.\n");
+    fprintf(stderr,
+           "\tforce [<hostname> [<disks>]* ]+\t# Force level 0 at next run.\n");
+    fprintf(stderr,
+           "\tunforce [<hostname> [<disks>]* ]+\t# Clear force command.\n");
+    fprintf(stderr,
+           "\tforce-bump [<hostname> [<disks>]* ]+\t# Force bump at next run.\n");
+    fprintf(stderr,
+           "\tforce-no-bump [<hostname> [<disks>]* ]+\t# Force no-bump at next run.\n");
+    fprintf(stderr,
+           "\tunforce-bump [<hostname> [<disks>]* ]+\t# Clear bump command.\n");
+    fprintf(stderr,
+           "\treuse <tapelabel> ...\t\t# re-use this tape.\n");
+    fprintf(stderr,
+           "\tno-reuse <tapelabel> ...\t# never re-use this tape.\n");
+    fprintf(stderr,
+           "\tfind [<hostname> [<disks>]* ]*\t# Show which tapes these dumps are on.\n");
+    fprintf(stderr,
+           "\tdelete [<hostname> [<disks>]* ]*\t# Delete from database.\n");
+    fprintf(stderr,
+           "\tinfo [<hostname> [<disks>]* ]*\t# Show current info records.\n");
+    fprintf(stderr,
+           "\tdue [<hostname> [<disks>]* ]*\t# Show due date.\n");
+    fprintf(stderr,
+           "\tbalance [-days <num>]\t\t# Show nightly dump size balance.\n");
+    fprintf(stderr,
+           "\ttape\t\t\t\t# Show which tape is due next.\n");
+    fprintf(stderr,
+           "\tbumpsize\t\t\t# Show current bump thresholds.\n");
+    fprintf(stderr,
+           "\texport [<hostname> [<disks>]* ]*\t# Export curinfo database to stdout.\n");
+    fprintf(stderr,
+           "\timport\t\t\t\t# Import curinfo database from stdin.\n");
+    fprintf(stderr,
+           "\tdisklist [<hostname> [<disks>]* ]*\t# Show disklist entries.\n");
+
+    exit(1);
+}
+
+
+/* ----------------------------------------------- */
+
+#define SECS_PER_DAY (24*60*60)
+time_t today;
+
+char *seqdatestr(seq)
+int seq;
+{
+    static char str[16];
+    static char *dow[7] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
+    time_t t = today + seq*SECS_PER_DAY;
+    struct tm *tm;
+
+    tm = localtime(&t);
+
+    ap_snprintf(str, sizeof(str),
+               "%2d/%02d %3s", tm->tm_mon+1, tm->tm_mday, dow[tm->tm_wday]);
+    return str;
+}
+
+#undef days_diff
+#define days_diff(a, b)        (((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;
+{
+    if(dp->strategy == DS_NOFULL)
+       return 1;       /* fake it */
+    if(info->inf[0].date < (time_t)0)
+       return 0;       /* new disk */
+    else
+       return dp->dumpcycle - days_diff(info->inf[0].date, today);
+}
+
+static void check_dumpuser()
+{
+    static int been_here = 0;
+    uid_t uid_me;
+    uid_t uid_dumpuser;
+    char *dumpuser;
+    struct passwd *pw;
+
+    if (been_here) {
+       return;
+    }
+    uid_me = getuid();
+    uid_dumpuser = uid_me;
+    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("ERROR: running as user \"%s\" instead of \"%s\"",
+             pw->pw_name, dumpuser);
+    }
+    been_here = 1;
+    return;
+}
+
+/* ----------------------------------------------- */
+
+void diskloop(argc, argv, cmdname, func)
+int argc;
+char **argv;
+char *cmdname;
+void (*func) P((disk_t *dp));
+{
+    disk_t *dp;
+    int count = 0;
+
+    if(argc < 4) {
+       fprintf(stderr,"%s: expecting \"%s [<hostname> [<disks>]* ]+\"\n",
+               get_pname(), cmdname);
+       usage();
+    }
+
+    match_disklist(diskqp, argc-3, argv+3);
+
+    for(dp = diskqp->head; dp != NULL; dp = dp->next) {
+       if(dp->todo) {
+           count++;
+           func(dp);
+       }
+    }
+    if(count==0) {
+       fprintf(stderr,"%s: no disk matched\n",get_pname());
+    }
+}
+
+/* ----------------------------------------------- */
+
+
+void force_one(dp)
+disk_t *dp;
+{
+    char *hostname = dp->host->hostname;
+    char *diskname = dp->name;
+    info_t info;
+
+#if TEXTDB
+    check_dumpuser();
+#endif
+    get_info(hostname, diskname, &info);
+    info.command |= FORCE_FULL;
+    if(info.command & FORCE_BUMP) {
+       info.command ^= FORCE_BUMP;
+       printf("%s: WARNING: %s:%s FORCE_BUMP command was cleared.\n",
+              get_pname(), hostname, diskname);
+    }
+    if(put_info(hostname, diskname, &info) == 0) {
+       printf("%s: %s:%s is set to a forced level 0 at next run.\n",
+              get_pname(), hostname, diskname);
+    } else {
+       fprintf(stderr, "%s: %s:%s could not be forced.\n",
+               get_pname(), hostname, diskname);
+    }
+}
+
+
+void force(argc, argv)
+int argc;
+char **argv;
+{
+    diskloop(argc, argv, "force", force_one);
+}
+
+
+/* ----------------------------------------------- */
+
+
+void unforce_one(dp)
+disk_t *dp;
+{
+    char *hostname = dp->host->hostname;
+    char *diskname = dp->name;
+    info_t info;
+
+    get_info(hostname, diskname, &info);
+    if(info.command & FORCE_FULL) {
+#if TEXTDB
+       check_dumpuser();
+#endif
+       info.command ^= FORCE_FULL;
+       if(put_info(hostname, diskname, &info) == 0){
+           printf("%s: force command for %s:%s cleared.\n",
+                  get_pname(), hostname, diskname);
+       } else {
+           fprintf(stderr,
+                   "%s: force command for %s:%s could not be cleared.\n",
+                   get_pname(), hostname, diskname);
+       }
+    }
+    else {
+       printf("%s: no force command outstanding for %s:%s, unchanged.\n",
+              get_pname(), hostname, diskname);
+    }
+}
+
+void unforce(argc, argv)
+int argc;
+char **argv;
+{
+    diskloop(argc, argv, "unforce", unforce_one);
+}
+
+
+/* ----------------------------------------------- */
+
+
+void force_bump_one(dp)
+disk_t *dp;
+{
+    char *hostname = dp->host->hostname;
+    char *diskname = dp->name;
+    info_t info;
+
+#if TEXTDB
+    check_dumpuser();
+#endif
+    get_info(hostname, diskname, &info);
+    info.command |= FORCE_BUMP;
+    if(info.command & FORCE_NO_BUMP) {
+       info.command ^= FORCE_NO_BUMP;
+       printf("%s: WARNING: %s:%s FORCE_NO_BUMP command was cleared.\n",
+              get_pname(), hostname, diskname);
+    }
+    if (info.command & FORCE_FULL) {
+       info.command ^= FORCE_FULL;
+       printf("%s: WARNING: %s:%s FORCE_FULL command was cleared.\n",
+              get_pname(), hostname, diskname);
+    }
+    if(put_info(hostname, diskname, &info) == 0) {
+       printf("%s: %s:%s is set to bump at next run.\n",
+              get_pname(), hostname, diskname);
+    } else {
+       fprintf(stderr, "%s: %s:%s could not be forced to bump.\n",
+               get_pname(), hostname, diskname);
+    }
+}
+
+
+void force_bump(argc, argv)
+int argc;
+char **argv;
+{
+    diskloop(argc, argv, "force-bump", force_bump_one);
+}
+
+
+/* ----------------------------------------------- */
+
+
+void force_no_bump_one(dp)
+disk_t *dp;
+{
+    char *hostname = dp->host->hostname;
+    char *diskname = dp->name;
+    info_t info;
+
+#if TEXTDB
+    check_dumpuser();
+#endif
+    get_info(hostname, diskname, &info);
+    info.command |= FORCE_NO_BUMP;
+    if(info.command & FORCE_BUMP) {
+       info.command ^= FORCE_BUMP;
+       printf("%s: WARNING: %s:%s FORCE_BUMP command was cleared.\n",
+              get_pname(), hostname, diskname);
+    }
+    if(put_info(hostname, diskname, &info) == 0) {
+       printf("%s: %s:%s is set to not bump at next run.\n",
+              get_pname(), hostname, diskname);
+    } else {
+       fprintf(stderr, "%s: %s:%s could not be force to not bump.\n",
+               get_pname(), hostname, diskname);
+    }
+}
+
+
+void force_no_bump(argc, argv)
+int argc;
+char **argv;
+{
+    diskloop(argc, argv, "force-no-bump", force_no_bump_one);
+}
+
+
+/* ----------------------------------------------- */
+
+
+void unforce_bump_one(dp)
+disk_t *dp;
+{
+    char *hostname = dp->host->hostname;
+    char *diskname = dp->name;
+    info_t info;
+
+    get_info(hostname, diskname, &info);
+    if(info.command & (FORCE_BUMP | FORCE_NO_BUMP)) {
+#if TEXTDB
+       check_dumpuser();
+#endif
+       if(info.command & FORCE_BUMP)
+           info.command ^= FORCE_BUMP;
+       if(info.command & FORCE_NO_BUMP)
+           info.command ^= FORCE_NO_BUMP;
+       if(put_info(hostname, diskname, &info) == 0) {
+           printf("%s: bump command for %s:%s cleared.\n",
+                  get_pname(), hostname, diskname);
+       } else {
+           fprintf(stderr, "%s: %s:%s bump command could not be cleared.\n",
+                   get_pname(), hostname, diskname);
+       }
+    }
+    else {
+       printf("%s: no bump command outstanding for %s:%s, unchanged.\n",
+              get_pname(), hostname, diskname);
+    }
+}
+
+
+void unforce_bump(argc, argv)
+int argc;
+char **argv;
+{
+    diskloop(argc, argv, "unforce-bump", unforce_bump_one);
+}
+
+
+/* ----------------------------------------------- */
+
+void reuse(argc, argv)
+int argc;
+char **argv;
+{
+    tape_t *tp;
+    int count;
+
+    if(argc < 4) {
+       fprintf(stderr,"%s: expecting \"reuse <tapelabel> ...\"\n",
+               get_pname());
+       usage();
+    }
+
+    check_dumpuser();
+    for(count=3; count< argc; count++) {
+       tp = lookup_tapelabel(argv[count]);
+       if ( tp == NULL) {
+           fprintf(stderr, "reuse: tape label %s not found in tapelist.\n",
+               argv[count]);
+           continue;
+       }
+       if( tp->reuse == 0 ) {
+           tp->reuse = 1;
+           printf("%s: marking tape %s as reusable.\n",
+                  get_pname(), argv[count]);
+       } else {
+           fprintf(stderr, "%s: tape %s already reusable.\n",
+                   get_pname(), argv[count]);
+       }
+    }
+
+    if(write_tapelist(conf_tapelist)) {
+       error("could not write tapelist \"%s\"", conf_tapelist);
+    }
+}
+
+void noreuse(argc, argv)
+int argc;
+char **argv;
+{
+    tape_t *tp;
+    int count;
+
+    if(argc < 4) {
+       fprintf(stderr,"%s: expecting \"no-reuse <tapelabel> ...\"\n",
+               get_pname());
+       usage();
+    }
+
+    check_dumpuser();
+    for(count=3; count< argc; count++) {
+       tp = lookup_tapelabel(argv[count]);
+       if ( tp == NULL) {
+           fprintf(stderr, "no-reuse: tape label %s not found in tapelist.\n",
+               argv[count]);
+           continue;
+       }
+       if( tp->reuse == 1 ) {
+           tp->reuse = 0;
+           printf("%s: marking tape %s as not reusable.\n",
+                  get_pname(), argv[count]);
+       } else {
+           fprintf(stderr, "%s: tape %s already not reusable.\n",
+                   get_pname(), argv[count]);
+       }
+    }
+
+    if(write_tapelist(conf_tapelist)) {
+       error("could not write tapelist \"%s\"", conf_tapelist);
+    }
+}
+
+
+/* ----------------------------------------------- */
+
+static int deleted;
+
+void delete_one(dp)
+disk_t *dp;
+{
+    char *hostname = dp->host->hostname;
+    char *diskname = dp->name;
+    info_t info;
+
+    if(get_info(hostname, diskname, &info)) {
+       printf("%s: %s:%s NOT currently in database.\n",
+              get_pname(), hostname, diskname);
+       return;
+    }
+
+    deleted++;
+    if(del_info(hostname, diskname))
+       error("couldn't delete %s:%s from database: %s",
+             hostname, diskname, strerror(errno));
+    else
+       printf("%s: %s:%s deleted from curinfo database.\n",
+              get_pname(), hostname, diskname);
+}
+
+void delete(argc, argv)
+int argc;
+char **argv;
+{
+    deleted = 0;
+    diskloop(argc, argv, "delete", delete_one);
+
+   if(deleted)
+       printf(
+        "%s: NOTE: you'll have to remove these from the disklist yourself.\n",
+        get_pname());
+}
+
+/* ----------------------------------------------- */
+
+void info_one(dp)
+disk_t *dp;
+{
+    info_t info;
+    int lev;
+    struct tm *tm;
+    stats_t *sp;
+
+    get_info(dp->host->hostname, dp->name, &info);
+
+    printf("\nCurrent info for %s %s:\n", dp->host->hostname, dp->name);
+    if(info.command & FORCE_FULL) 
+       printf("  (Forcing to level 0 dump at next run)\n");
+    if(info.command & FORCE_BUMP) 
+       printf("  (Forcing bump at next run)\n");
+    if(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",
+          info.full.rate[0], info.full.rate[1], info.full.rate[2]);
+    printf("                    Incremental:  %5.1f, %5.1f, %5.1f\n",
+          info.incr.rate[0], info.incr.rate[1], info.incr.rate[2]);
+    printf("          compressed size, Full: %5.1f%%,%5.1f%%,%5.1f%%\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",
+          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);
+    }
+}
+
+
+void info(argc, argv)
+int argc;
+char **argv;
+{
+    disk_t *dp;
+
+    if(argc >= 4)
+       diskloop(argc, argv, "info", info_one);
+    else
+       for(dp = diskqp->head; dp != NULL; dp = dp->next)
+           info_one(dp);
+}
+
+/* ----------------------------------------------- */
+
+void due_one(dp)
+disk_t *dp;
+{
+    host_t *hp;
+    int days;
+    info_t info;
+
+    hp = dp->host;
+    if(get_info(hp->hostname, dp->name, &info)) {
+       printf("new disk %s:%s ignored.\n", hp->hostname, dp->name);
+    }
+    else {
+       days = next_level0(dp, &info);
+       if(days < 0) {
+           printf("Overdue %2d day%s %s:%s\n",
+                  -days, (-days == 1) ? ": " : "s:",
+                  hp->hostname, dp->name);
+       }
+       else if(days == 0) {
+           printf("Due today: %s:%s\n", hp->hostname, dp->name);
+       }
+       else {
+           printf("Due in %2d day%s %s:%s\n", days,
+                  (days == 1) ? ": " : "s:",
+                  hp->hostname, dp->name);
+       }
+    }
+}
+
+void due(argc, argv)
+int argc;
+char **argv;
+{
+    disk_t *dp;
+
+    time(&today);
+    if(argc >= 4)
+       diskloop(argc, argv, "due", due_one);
+    else
+       for(dp = diskqp->head; dp != NULL; dp = dp->next)
+           due_one(dp);
+}
+
+/* ----------------------------------------------- */
+
+void tape()
+{
+    tape_t *tp, *lasttp;
+    int runtapes, i;
+
+    runtapes = getconf_int(CNF_RUNTAPES);
+    tp = lookup_last_reusable_tape(0);
+
+    for ( i=0 ; i < runtapes ; i++ ) {
+       printf("The next Amanda run should go onto ");
+
+       if(tp != NULL)
+           printf("tape %s or ", tp->label);
+       printf("a new tape.\n");
+       
+       tp = lookup_last_reusable_tape(i + 1);
+    }
+    lasttp = lookup_tapepos(lookup_nb_tape());
+    i = runtapes;
+    if(lasttp && i > 0 && lasttp->datestamp == 0) {
+       int c = 0;
+       while(lasttp && i > 0 && lasttp->datestamp == 0) {
+           c++;
+           lasttp = lasttp->prev;
+           i--;
+       }
+       lasttp = lookup_tapepos(lookup_nb_tape());
+       i = runtapes;
+       if(c == 1) {
+           printf("The next new tape already labelled is: %s.\n",
+                  lasttp->label);
+       }
+       else {
+           printf("The next %d new tapes already labelled are: %s", c,
+                  lasttp->label);
+           lasttp = lasttp->prev;
+           c--;
+           while(lasttp && c > 0 && lasttp->datestamp == 0) {
+               printf(", %s", lasttp->label);
+               lasttp = lasttp->prev;
+               c--;
+           }
+           printf(".\n");
+       }
+    }
+}
+
+/* ----------------------------------------------- */
+
+void balance(argc, argv)
+int argc;
+char **argv;
+{
+    disk_t *dp;
+    struct balance_stats {
+       int disks;
+       long 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;
+    info_t info;
+    long int total_balanced, balanced;
+
+    time(&today);
+    conf_dumpcycle = getconf_int(CNF_DUMPCYCLE);
+    conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
+    later = conf_dumpcycle;
+    overdue = 0;
+    max_overdue = 0;
+
+    if(argc > 4 && strcmp(argv[3],"--days") == 0) {
+       later = atoi(argv[4]);
+       if(later < 0) later = conf_dumpcycle;
+    }
+
+    if(conf_runspercycle == 0) {
+       runs_per_cycle = conf_dumpcycle;
+    } else if(conf_runspercycle == -1 ) {
+       runs_per_cycle = guess_runs_from_tapelist();
+    } else
+       runs_per_cycle = conf_runspercycle;
+
+    if (runs_per_cycle <= 0) {
+       runs_per_cycle = 1;
+    }
+
+    total = later + 1;
+    balance = later + 2;
+    distinct = later + 3;
+
+    sp = (struct balance_stats *)
+       alloc(sizeof(struct balance_stats) * (distinct+1));
+
+    for(seq=0; seq <= distinct; seq++)
+       sp[seq].disks = sp[seq].origsize = sp[seq].outsize = 0;
+
+    for(dp = diskqp->head; dp != NULL; dp = dp->next) {
+       if(get_info(dp->host->hostname, dp->name, &info)) {
+           printf("new disk %s:%s ignored.\n", dp->host->hostname, dp->name);
+           continue;
+       }
+       if (dp->strategy == DS_NOFULL) {
+           continue;
+       }
+       sp[distinct].disks++;
+       sp[distinct].origsize += info.inf[0].size;
+       sp[distinct].outsize += info.inf[0].csize;
+
+       sp[balance].disks++;
+       if(dp->dumpcycle == 0) {
+           sp[balance].origsize += info.inf[0].size * runs_per_cycle;
+           sp[balance].outsize += info.inf[0].csize * runs_per_cycle;
+       }
+       else {
+           sp[balance].origsize += info.inf[0].size *
+                                   (conf_dumpcycle / dp->dumpcycle);
+           sp[balance].outsize += info.inf[0].csize *
+                                  (conf_dumpcycle / dp->dumpcycle);
+       }
+
+       disk_dumpcycle = dp->dumpcycle;
+       if(dp->dumpcycle <= 0)
+           disk_dumpcycle = ((float)conf_dumpcycle) / ((float)runs_per_cycle);
+
+       seq = next_level0(dp, &info);
+       fseq = seq + 0.0001;
+       do {
+           if(seq < 0) {
+               overdue++;
+               if (-seq > max_overdue)
+                   max_overdue = -seq;
+               seq = 0;
+               fseq = seq + 0.0001;
+           }
+           if(seq > later) {
+               seq = later;
+           }
+           
+           sp[seq].disks++;
+           sp[seq].origsize += info.inf[0].size;
+           sp[seq].outsize += info.inf[0].csize;
+
+           if(seq < later) {
+               sp[total].disks++;
+               sp[total].origsize += info.inf[0].size;
+               sp[total].outsize += info.inf[0].csize;
+           }
+           
+           /* See, if there's another run in this dumpcycle */
+           fseq += disk_dumpcycle;
+           seq = fseq;
+       } while (seq < later);
+    }
+
+    if(sp[total].outsize == 0) {
+       printf("\nNo data to report on yet.\n");
+       amfree(sp);
+       return;
+    }
+
+    balanced = sp[balance].outsize / runs_per_cycle;
+    if(conf_dumpcycle == later) {
+       total_balanced = sp[total].outsize / runs_per_cycle;
+    }
+    else {
+       total_balanced = 1024*(((sp[total].outsize/1024) * conf_dumpcycle)
+                           / (runs_per_cycle * later));
+    }
+
+    printf("\n due-date  #fs    orig KB     out KB   balance\n");
+    printf("----------------------------------------------\n");
+    for(seq = 0; seq < later; seq++) {
+       printf("%-9.9s  %3d %10ld %10ld ",
+              seqdatestr(seq), sp[seq].disks,
+              sp[seq].origsize, sp[seq].outsize);
+       if(!sp[seq].outsize) printf("     --- \n");
+       else printf("%+8.1f%%\n",
+                   (sp[seq].outsize-balanced)*100.0/(double)balanced);
+    }
+    if(sp[later].disks != 0) {
+       printf("later      %3d %10ld %10ld ",
+              sp[later].disks,
+              sp[later].origsize, sp[later].outsize);
+       if(!sp[later].outsize) printf("     --- \n");
+       else printf("%+8.1f%%\n",
+                   (sp[later].outsize-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);
+    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);
+    }
+    if (sp[distinct].disks != sp[total].disks) {
+       printf("DISTINCT   %3d %10ld %10ld\n", sp[distinct].disks,
+              sp[distinct].origsize, sp[distinct].outsize);
+    }
+    printf("  (estimated %d run%s per dumpcycle)\n",
+          runs_per_cycle, (runs_per_cycle == 1) ? "" : "s");
+    if (overdue) {
+       printf(" (%d filesystem%s overdue, the most being overdue %d day%s)\n",
+              overdue, (overdue == 1) ? "" : "s",
+              max_overdue, (max_overdue == 1) ? "" : "s");
+    }
+    amfree(sp);
+}
+
+
+/* ----------------------------------------------- */
+
+void find(argc, argv)
+int argc;
+char **argv;
+{
+    int start_argc;
+    char *sort_order = NULL;
+    find_result_t *output_find;
+
+    if(argc < 3) {
+       fprintf(stderr,
+               "%s: expecting \"find [--sort <hkdlb>] [hostname [<disk>]]*\"\n",
+               get_pname());
+       usage();
+    }
+
+
+    sort_order = newstralloc(sort_order, DEFAULT_SORT_ORDER);
+    if(argc > 4 && strcmp(argv[3],"--sort") == 0) {
+       int i, valid_sort=1;
+
+       for(i=strlen(argv[4])-1;i>=0;i--) {
+           switch (argv[4][i]) {
+           case 'h':
+           case 'H':
+           case 'k':
+           case 'K':
+           case 'd':
+           case 'D':
+           case 'l':
+           case 'L':
+           case 'b':
+           case 'B':
+                   break;
+           default: valid_sort=0;
+           }
+       }
+       if(valid_sort) {
+           sort_order = newstralloc(sort_order, argv[4]);
+       } else {
+           printf("Invalid sort order: %s\n", argv[4]);
+           printf("Use default sort order: %s\n", sort_order);
+       }
+       start_argc=6;
+    } else {
+       start_argc=4;
+    }
+    match_disklist(diskqp, argc-(start_argc-1), argv+(start_argc-1));
+    output_find = find_dump(1, diskqp);
+
+    if(argc-(start_argc-1) > 0) {
+       free_find_result(&output_find);
+       match_disklist(diskqp, argc-(start_argc-1), argv+(start_argc-1));
+       output_find = find_dump(0, NULL);
+    }
+
+    sort_find_result(sort_order, &output_find);
+    print_find_result(output_find);
+    free_find_result(&output_find);
+
+    amfree(sort_order);
+}
+
+
+/* ------------------------ */
+
+
+/* shared code with planner.c */
+
+int bump_thresh(level)
+int level;
+{
+    int bump = getconf_int(CNF_BUMPSIZE);
+    double mult = getconf_real(CNF_BUMPMULT);
+
+    while(--level) bump = (int) bump * mult;
+    return bump;
+}
+
+void bumpsize()
+{
+    int l;
+
+    printf("Current bump parameters:\n");
+    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",
+          getconf_real(CNF_BUMPMULT));
+
+    printf("      Bump -> To  Threshold\n");
+    for(l = 1; l < 9; l++) {
+       printf("\t%d  ->  %d  %9d KB\n", l, l+1, bump_thresh(l));
+    }
+    putchar('\n');
+}
+
+/* ----------------------------------------------- */
+
+void export_one P((disk_t *dp));
+
+void export_db(argc, argv)
+int argc;
+char **argv;
+{
+    disk_t *dp;
+    time_t curtime;
+    char hostname[MAX_HOSTNAME_LENGTH+1];
+    int i;
+
+    printf("CURINFO Version %s CONF %s\n", version(), getconf_str(CNF_ORG));
+
+    curtime = time(0);
+    if(gethostname(hostname, sizeof(hostname)-1) == -1) {
+       error("could not determine host name: %s", strerror(errno));
+    }
+    hostname[sizeof(hostname)-1] = '\0';
+    printf("# Generated by:\n#    host: %s\n#    date: %s",
+          hostname, ctime(&curtime));
+
+    printf("#    command:");
+    for(i = 0; i < argc; i++) {
+       printf(" %s", argv[i]);
+    }
+
+    printf("\n# This file can be merged back in with \"amadmin import\".\n");
+    printf("# Edit only with care.\n");
+
+    if(argc >= 4) {
+       diskloop(argc, argv, "export", export_one);
+    } else for(dp = diskqp->head; dp != NULL; dp = dp->next) {
+       export_one(dp);
+    }
+}
+
+void export_one(dp)
+disk_t *dp;
+{
+    info_t info;
+    int i,l;
+
+    if(get_info(dp->host->hostname, dp->name, &info)) {
+       fprintf(stderr, "Warning: no curinfo record for %s:%s\n",
+               dp->host->hostname, dp->name);
+       return;
+    }
+    printf("host: %s\ndisk: %s\n", dp->host->hostname, dp->name);
+    printf("command: %d\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]);
+    printf("\nfull-comp:");
+    for(i=0;i<AVG_COUNT;i++) printf(" %f", info.full.comp[i]);
+
+    printf("\nincr-rate:");
+    for(i=0;i<AVG_COUNT;i++) printf(" %f", info.incr.rate[i]);
+    printf("\nincr-comp:");
+    for(i=0;i<AVG_COUNT;i++) printf(" %f", 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,
+              info.inf[l].label);
+    }
+    printf("//\n");
+}
+
+/* ----------------------------------------------- */
+
+int import_one P((void));
+char *impget_line P((void));
+
+void import_db(argc, argv)
+int argc;
+char **argv;
+{
+    int vers_maj, vers_min, vers_patch, newer;
+    char *org;
+    char *line = NULL;
+    char *hdr;
+    char *s;
+    int ch;
+
+    /* process header line */
+
+    if((line = agets(stdin)) == NULL) {
+       fprintf(stderr, "%s: empty input.\n", get_pname());
+       return;
+    }
+
+    s = line;
+    ch = *s++;
+
+    hdr = "version";
+#define sc "CURINFO Version"
+    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       goto bad_header;
+    }
+    s += sizeof(sc)-1;
+    ch = *s++;
+#undef sc
+    skip_whitespace(s, ch);
+    if(ch == '\0'
+       || sscanf(s - 1, "%d.%d.%d", &vers_maj, &vers_min, &vers_patch) != 3) {
+       goto bad_header;
+    }
+
+    skip_integer(s, ch);                       /* skip over major */
+    if(ch != '.') {
+       goto bad_header;
+    }
+    ch = *s++;
+    skip_integer(s, ch);                       /* skip over minor */
+    if(ch != '.') {
+       goto bad_header;
+    }
+    ch = *s++;
+    skip_integer(s, ch);                       /* skip over patch */
+
+    hdr = "comment";
+    if(ch == '\0') {
+       goto bad_header;
+    }
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    hdr = "CONF";
+    skip_whitespace(s, ch);                    /* find the org keyword */
+#define sc "CONF"
+    if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       goto bad_header;
+    }
+    s += sizeof(sc)-1;
+    ch = *s++;
+#undef sc
+
+    hdr = "org";
+    skip_whitespace(s, ch);                    /* find the org string */
+    if(ch == '\0') {
+       goto bad_header;
+    }
+    org = s - 1;
+
+    newer = (vers_maj != VERSION_MAJOR)? vers_maj > VERSION_MAJOR :
+           (vers_min != VERSION_MINOR)? vers_min > VERSION_MINOR :
+                                        vers_patch > VERSION_PATCH;
+    if(newer)
+       fprintf(stderr,
+            "%s: WARNING: input is from newer Amanda version: %d.%d.%d.\n",
+               get_pname(), vers_maj, vers_min, vers_patch);
+
+    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());
+
+    amfree(line);
+    return;
+
+ bad_header:
+
+    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");
+    return;
+}
+
+
+int import_one P((void))
+{
+    info_t info;
+    stats_t onestat;
+    int rc, level;
+    long onedate;
+    char *line = NULL;
+    char *s, *fp;
+    int ch;
+    char *hostname = NULL;
+    char *diskname = NULL;
+
+#if TEXTDB
+    check_dumpuser();
+#endif
+
+    memset(&info, 0, sizeof(info_t));
+
+    for(level = 0; level < DUMP_LEVELS; level++) {
+        info.inf[level].date = (time_t)-1;
+    }
+
+    /* get host: disk: command: lines */
+
+    hostname = diskname = NULL;
+
+    if((line = impget_line()) == NULL) return 0;       /* nothing there */
+    s = line;
+    ch = *s++;
+
+    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;
+    ch = s[-1];
+#undef sc
+    skip_whitespace(s, ch);
+    if(ch == '\0') goto parse_err;
+    fp = s-1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    hostname = stralloc(fp);
+    s[-1] = ch;
+
+    skip_whitespace(s, ch);
+    while (ch == 0) {
+      amfree(line);
+      if((line = impget_line()) == NULL) goto shortfile_err;
+      s = line;
+      ch = *s++;
+      skip_whitespace(s, ch);
+    }
+#define sc "disk:"
+    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);
+    if(ch == '\0') goto parse_err;
+    fp = s-1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    diskname = stralloc(fp);
+    s[-1] = ch;
+
+    amfree(line);
+    if((line = impget_line()) == NULL) goto shortfile_err;
+    if(sscanf(line, "command: %d", &info.command) != 1) goto parse_err;
+
+    /* get last_level and consecutive_runs */
+
+    amfree(line);
+    if((line = impget_line()) == NULL) goto shortfile_err;
+    rc = sscanf(line, "last_level: %d", &info.last_level);
+    if(rc == 1) {
+       amfree(line);
+       if((line = impget_line()) == NULL) goto shortfile_err;
+       if(sscanf(line, "consecutive_runs: %d", &info.consecutive_runs) != 1) goto parse_err;
+       amfree(line);
+       if((line = impget_line()) == NULL) goto shortfile_err;
+    }
+
+    /* get rate: and comp: lines for full dumps */
+
+    rc = sscanf(line, "full-rate: %f %f %f",
+               &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",
+               &info.full.comp[0], &info.full.comp[1], &info.full.comp[2]);
+    if(rc != 3) goto parse_err;
+
+    /* get rate: and comp: lines for incr dumps */
+
+    amfree(line);
+    if((line = impget_line()) == NULL) goto shortfile_err;
+    rc = sscanf(line, "incr-rate: %f %f %f",
+               &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",
+               &info.incr.comp[0], &info.incr.comp[1], &info.incr.comp[2]);
+    if(rc != 3) goto parse_err;
+
+    /* get stats for dump levels */
+
+    while(1) {
+       amfree(line);
+       if((line = impget_line()) == NULL) goto shortfile_err;
+       if(strncmp(line, "//", 2) == 0) {
+           /* end of record */
+           break;
+       }
+       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) {
+           goto parse_err;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           goto parse_err;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.size) != 1) {
+           goto parse_err;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.csize) != 1) {
+           goto parse_err;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%ld", &onestat.secs) != 1) {
+           goto parse_err;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%ld", &onedate) != 1) {
+           goto parse_err;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch != '\0') {
+           if(sscanf(s - 1, "%d", &onestat.filenum) != 1) {
+               goto parse_err;
+           }
+           skip_integer(s, ch);
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               if (onestat.filenum != 0)
+                   goto parse_err;
+               onestat.label[0] = '\0';
+           } else {
+               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;
+       if(level < 0 || level > 9) goto parse_err;
+
+       info.inf[level] = onestat;
+    }
+    amfree(line);
+
+    /* got a full record, now write it out to the database */
+
+    if(put_info(hostname, diskname, &info)) {
+       fprintf(stderr, "%s: error writing record for %s:%s\n",
+               get_pname(), hostname, diskname);
+    }
+    amfree(hostname);
+    amfree(diskname);
+    return 1;
+
+ parse_err:
+    amfree(line);
+    amfree(hostname);
+    amfree(diskname);
+    fprintf(stderr, "%s: parse error reading import record.\n", get_pname());
+    return 0;
+
+ shortfile_err:
+    amfree(line);
+    amfree(hostname);
+    amfree(diskname);
+    fprintf(stderr, "%s: short file reading import record.\n", get_pname());
+    return 0;
+}
+
+char *
+impget_line ()
+{
+    char *line;
+    char *s;
+    int ch;
+
+    for(; (line = agets(stdin)) != NULL; free(line)) {
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+       if(ch == '#') {
+           /* ignore comment lines */
+           continue;
+       } else if(ch) {
+           /* found non-blank, return line */
+           return line;
+       }
+       /* otherwise, a blank line, so keep going */
+    }
+    if(ferror(stdin)) {
+       fprintf(stderr, "%s: reading stdin: %s\n",
+               get_pname(), strerror(errno));
+    }
+    return NULL;
+}
+
+/* ----------------------------------------------- */
+
+void disklist_one(dp)
+disk_t *dp;
+{
+    host_t *hp;
+    interface_t *ip;
+    sle_t *excl;
+
+    hp = dp->host;
+    ip = hp->netif;
+
+    printf("line %d:\n", dp->line);
+
+    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);
+
+    printf("        program \"%s\"\n", dp->program);
+    if(dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
+       printf("        exclude file");
+       for(excl = dp->exclude_file->first; excl != NULL; excl = excl->next) {
+           printf(" \"%s\"", excl->name);
+       }
+       printf("\n");
+    }
+    if(dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
+       printf("        exclude list");
+       if(dp->exclude_optional) printf(" optional");
+       for(excl = dp->exclude_list->first; excl != NULL; excl = excl->next) {
+           printf(" \"%s\"", excl->name);
+       }
+       printf("\n");
+    }
+    if(dp->include_file != NULL && dp->include_file->nb_element > 0) {
+       printf("        include file");
+       for(excl = dp->include_file->first; excl != NULL; excl = excl->next) {
+           printf(" \"%s\"", excl->name);
+       }
+       printf("\n");
+    }
+    if(dp->include_list != NULL && dp->include_list->nb_element > 0) {
+       printf("        include list");
+       if(dp->include_optional) printf(" optional");
+       for(excl = dp->include_list->first; excl != NULL; excl = excl->next) {
+           printf(" \"%s\"", excl->name);
+       }
+       printf("\n");
+    }
+    printf("        priority %ld\n", dp->priority);
+    printf("        dumpcycle %ld\n", dp->dumpcycle);
+    printf("        maxdumps %d\n", dp->maxdumps);
+    printf("        maxpromoteday %d\n", dp->maxpromoteday);
+
+    printf("        strategy ");
+    switch(dp->strategy) {
+    case DS_SKIP:
+       printf("SKIP\n");
+       break;
+    case DS_STANDARD:
+       printf("STANDARD\n");
+       break;
+    case DS_NOFULL:
+       printf("NOFULL\n");
+       break;
+    case DS_NOINC:
+       printf("NOINC\n");
+       break;
+    case DS_HANOI:
+       printf("HANOI\n");
+       break;
+    case DS_INCRONLY:
+       printf("INCRONLY\n");
+       break;
+    }
+
+    printf("        compress ");
+    switch(dp->compress) {
+    case COMP_NONE:
+       printf("NONE\n");
+       break;
+    case COMP_FAST:
+       printf("CLIENT FAST\n");
+       break;
+    case COMP_BEST:
+       printf("CLIENT BEST\n");
+       break;
+    case COMP_SERV_FAST:
+       printf("SERVER FAST\n");
+       break;
+    case COMP_SERV_BEST:
+       printf("SERVER BEST\n");
+       break;
+    }
+    if(dp->compress != COMP_NONE) {
+       printf("        comprate %.2f %.2f\n",
+              dp->comprate[0], dp->comprate[1]);
+    }
+
+    printf("        auth ");
+    switch(dp->auth) {
+    case AUTH_BSD:
+       printf("BSD\n");
+       break;
+    case AUTH_KRB4:
+       printf("KRB4\n");
+       break;
+    }
+    printf("        kencrypt %s\n", (dp->kencrypt? "YES" : "NO"));
+
+    printf("        holdingdisk %s\n", (!dp->no_hold? "YES" : "NO"));
+    printf("        record %s\n", (dp->record? "YES" : "NO"));
+    printf("        index %s\n", (dp->index? "YES" : "NO"));
+    printf("        skip-incr %s\n", (dp->skip_incr? "YES" : "NO"));
+    printf("        skip-full %s\n", (dp->skip_full? "YES" : "NO"));
+
+    printf("\n");
+}
+
+void disklist(argc, argv)
+int argc;
+char **argv;
+{
+    disk_t *dp;
+
+    if(argc >= 4)
+       diskloop(argc, argv, "disklist", disklist_one);
+    else
+       for(dp = diskqp->head; dp != NULL; dp = dp->next)
+           disklist_one(dp);
+}
diff --git a/server-src/amcheck.c b/server-src/amcheck.c
new file mode 100644 (file)
index 0000000..f7fb4fc
--- /dev/null
@@ -0,0 +1,1648 @@
+/*
+ * 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: amcheck.c,v 1.50.2.19.2.7.2.22 2004/03/16 19:03:39 martinea Exp $
+ *
+ * checks for common problems in server and clients
+ */
+#include "amanda.h"
+#include "conffile.h"
+#include "statfs.h"
+#include "diskfile.h"
+#include "tapefile.h"
+#include "tapeio.h"
+#include "changer.h"
+#include "protocol.h"
+#include "clock.h"
+#include "version.h"
+#include "amindex.h"
+#include "token.h"
+#include "util.h"
+#include "pipespawn.h"
+#include "amfeatures.h"
+
+/*
+ * If we don't have the new-style wait access functions, use our own,
+ * compatible with old-style BSD systems at least.  Note that we don't
+ * care about the case w_stopval == WSTOPPED since we don't ask to see
+ * stopped processes, so should never get them from wait.
+ */
+#ifndef WEXITSTATUS
+#   define WEXITSTATUS(r)       (((union wait *) &(r))->w_retcode)
+#   define WTERMSIG(r)          (((union wait *) &(r))->w_termsig)
+
+#   undef WIFSIGNALED
+#   define WIFSIGNALED(r)        (((union wait *) &(r))->w_termsig != 0)
+#endif
+
+#define BUFFER_SIZE    32768
+
+static int conf_ctimeout;
+static int overwrite;
+dgram_t *msg = NULL;
+
+static disklist_t *origqp;
+
+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 scan_init P((int rc, int ns, int bk));
+int taperscan_slot P((int rc, char *slotstr, char *device));
+char *taper_scan P((void));
+int test_server_pgm P((FILE *outf, char *dir, char *pgm,
+                      int suid, uid_t dumpuid));
+
+void usage()
+{
+    error("Usage: amcheck%s [-M <username>] [-mawsclt] <conf> [host [disk]* ]*", versionsuffix());
+}
+
+static unsigned long malloc_hist_1, malloc_size_1;
+static unsigned long malloc_hist_2, malloc_size_2;
+
+static am_feature_t *our_features = NULL;
+static char *our_feature_string = NULL;
+
+int main(argc, argv)
+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, result_port, tempfd, mainfd;
+    amwait_t retstat;
+    pid_t pid;
+    extern int optind;
+    int l, n, s;
+    int fd;
+    char *mailto = NULL;
+    extern char *optarg;
+    int mailout;
+    int alwaysmail;
+    char *tempfname = NULL;
+    char *conffile;
+    char *conf_diskfile;
+    char *dumpuser;
+    struct passwd *pw;
+    uid_t uid_me;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amcheck");
+    dbopen();
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    ap_snprintf(pid_str, sizeof(pid_str), "%ld", (long)getpid());
+
+    erroutput_type = ERR_INTERACTIVE;
+
+    our_features = am_init_feature_set();
+    our_feature_string = am_feature_to_string(our_features);
+
+    /* set up dgram port first thing */
+
+    msg = dgram_alloc();
+
+    if(dgram_bind(msg, &result_port) == -1)
+       error("could not bind result datagram port: %s", strerror(errno));
+
+    if(geteuid() == 0) {
+       /* set both real and effective uid's to real uid, likewise for gid */
+       setgid(getgid());
+       setuid(getuid());
+    }
+    uid_me = getuid();
+
+    alwaysmail = mailout = overwrite = 0;
+    do_localchk = do_tapechk = do_clientchk = 0;
+    chk_flag = 0;
+    server_probs = client_probs = 0;
+    tempfd = mainfd = -1;
+
+    /* process arguments */
+
+    while((opt = getopt(argc, argv, "M:mawsclt")) != EOF) {
+       switch(opt) {
+       case 'M':       mailto=stralloc(optarg);
+       case 'm':       
+#ifdef MAILER
+                       mailout = 1;
+#else
+                       printf("You can't use -%c because configure didn't find a mailer.\n",
+                               opt);
+                       exit(1);
+#endif
+                       break;
+       case 'a':       
+#ifdef MAILER
+                       mailout = 1;
+                       alwaysmail = 1;
+#else
+                       printf("You can't use -%c because configure didn't find a mailer.\n",
+                               opt);
+                       exit(1);
+#endif
+                       break;
+       case 's':       do_localchk = 1; do_tapechk = 1;
+                       chk_flag = 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;
+                       break;
+       case 't':       do_tapechk = 1;
+                       chk_flag = 1;
+                       break;
+       case '?':
+       default:
+           usage();
+       }
+    }
+    argc -= optind, argv += optind;
+    if(! chk_flag) {
+       do_localchk = do_clientchk = do_tapechk = 1;
+    }
+
+    if(argc < 1) usage();
+
+    config_name = stralloc(*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);
+    }
+    amfree(conffile);
+    conf_ctimeout = getconf_int(CNF_CTIMEOUT);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((origqp = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist %s", conf_diskfile);
+    }
+    match_disklist(origqp, argc-1, argv+1);
+    amfree(conf_diskfile);
+
+    /*
+     * Make sure we are running as the dump user.
+     */
+    dumpuser = getconf_str(CNF_DUMPUSER);
+    if ((pw = getpwnam(dumpuser)) == NULL) {
+       error("cannot look up dump user \"%s\"", dumpuser);
+    }
+    uid_dumpuser = pw->pw_uid;
+    if ((pw = getpwuid(uid_me)) == NULL) {
+       error("cannot look up my own uid (%ld)", (long)uid_me);
+    }
+    if (uid_me != uid_dumpuser) {
+       error("running as user \"%s\" instead of \"%s\"",
+             pw->pw_name,
+             dumpuser);
+    }
+
+    /*
+     * If both server and client side checks are being done, the server
+     * check output goes to the main output, while the client check output
+     * goes to a temporary file and is copied to the main output when done.
+     *
+     * If the output is to be mailed, the main output is also a disk file,
+     * otherwise it is stdout.
+     */
+    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)
+           error("could not open %s: %s", tempfname, strerror(errno));
+       unlink(tempfname);                      /* so it goes away on close */
+       amfree(tempfname);
+    }
+
+    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)
+           error("could not open %s: %s", mainfname, strerror(errno));
+       unlink(mainfname);                      /* so it goes away on close */
+       amfree(mainfname);
+    }
+    else
+       /* just use stdout */
+       mainfd = 1;
+
+    /* start server side checks */
+
+    if(do_localchk || do_tapechk) {
+       serverchk_pid = start_server_check(mainfd, do_localchk, do_tapechk);
+    } else {
+       serverchk_pid = 0;
+    }
+
+    /* start client side checks */
+
+    if(do_clientchk) {
+       clientchk_pid = start_client_checks((do_localchk || do_tapechk) ? tempfd : mainfd);
+    } else {
+       clientchk_pid = 0;
+    }
+
+    /* wait for child processes and note any problems */
+
+    while(1) {
+       if((pid = wait(&retstat)) == -1) {
+           if(errno == EINTR) continue;
+           else break;
+       } else if(pid == clientchk_pid) {
+           client_probs = WIFSIGNALED(retstat) || WEXITSTATUS(retstat);
+           clientchk_pid = 0;
+       } else if(pid == serverchk_pid) {
+           server_probs = WIFSIGNALED(retstat) || WEXITSTATUS(retstat);
+           serverchk_pid = 0;
+       } else {
+           char number[NUM_STR_SIZE];
+           char *wait_msg = NULL;
+
+           ap_snprintf(number, sizeof(number), "%ld", (long)pid);
+           wait_msg = vstralloc("parent: reaped bogus pid ", number, "\n",
+                                NULL);
+           for(l = 0, n = strlen(wait_msg); l < n; l += s) {
+               if((s = write(mainfd, wait_msg + l, n - l)) < 0) {
+                   error("write main file: %s", strerror(errno));
+               }
+           }
+           amfree(wait_msg);
+       }
+    }
+    amfree(msg);
+
+    /* copy temp output to main output and write tagline */
+
+    if(do_clientchk && (do_localchk || do_tapechk)) {
+       if(lseek(tempfd, 0, 0) == -1)
+           error("seek temp file: %s", strerror(errno));
+
+       while((size=read(tempfd, buffer, sizeof(buffer))) > 0) {
+           for(l = 0; l < size; l += s) {
+               if((s = write(mainfd, buffer + l, size - l)) < 0) {
+                   error("write main file: %s", strerror(errno));
+               }
+           }
+       }
+       if(size < 0)
+           error("read temp file: %s", strerror(errno));
+       aclose(tempfd);
+    }
+
+    version_string = vstralloc("\n",
+                              "(brought to you by Amanda ", version(), ")\n",
+                              NULL);
+    for(l = 0, n = strlen(version_string); l < n; l += s) {
+       if((s = write(mainfd, version_string + l, n - l)) < 0) {
+           error("write main file: %s", strerror(errno));
+       }
+    }
+    amfree(version_string);
+    amfree(config_dir);
+    amfree(config_name);
+    amfree(our_feature_string);
+    am_release_feature_set(our_features);
+    our_features = NULL;
+
+    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);
+    }
+
+    /* send mail if requested, but only if there were problems */
+#ifdef MAILER
+
+#define        MAILTO_LIMIT    10
+
+    if((server_probs || client_probs || alwaysmail) && mailout) {
+       int mailfd;
+       int nullfd;
+       int errfd;
+       FILE *ferr;
+       char *subject;
+       char **a;
+       amwait_t retstat;
+       pid_t mailpid;
+       pid_t wpid;
+       int r;
+       int w;
+       char *err = NULL;
+       char *extra_info = NULL;
+       char *line = NULL;
+       int ret;
+       int rc;
+       int sig;
+       char number[NUM_STR_SIZE];
+
+       fflush(stdout);
+       if(lseek(mainfd, (off_t)0, SEEK_SET) == -1) {
+           error("lseek main file: %s", strerror(errno));
+       }
+       if(alwaysmail && !(server_probs || client_probs)) {
+           subject = stralloc2(getconf_str(CNF_ORG),
+                           " AMCHECK REPORT: NO PROBLEMS FOUND");
+       } else {
+           subject = stralloc2(getconf_str(CNF_ORG),
+                           " AMANDA PROBLEM: FIX BEFORE RUN, IF POSSIBLE");
+       }
+       /*
+        * Variable arg lists are hard to deal with when we do not know
+        * ourself how many args are involved.  Split the address list
+        * and hope there are not more than 9 entries.
+        *
+        * 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 *));
+       if(mailto) {
+           a[1] = mailto;
+           a[2] = NULL;
+       } else {
+           n = split(getconf_str(CNF_MAILTO), a, MAILTO_LIMIT, " ");
+           a[n + 1] = NULL;
+       }
+       if((nullfd = open("/dev/null", O_RDWR)) < 0) {
+           error("nullfd: /dev/null: %s", strerror(errno));
+       }
+       mailpid = pipespawn(MAILER, STDIN_PIPE | STDERR_PIPE,
+                           &mailfd, &nullfd, &errfd,
+                           MAILER,
+                           "-s", subject,
+                                 a[1], a[2], a[3], a[4],
+                           a[5], a[6], a[7], a[8], a[9],
+                           NULL);
+       amfree(subject);
+       /*
+        * There is the potential for a deadlock here since we are writing
+        * to the process and then reading stderr, but in the normal case,
+        * nothing should be coming back to us, and hopefully in error
+        * 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) {
+               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));
+               } else {
+                   error("mailfd write: wrote %d instead of %d", w, r);
+               }
+           }
+       }
+       aclose(mailfd);
+       ferr = fdopen(errfd, "r");
+       for(; (line = agets(ferr)) != NULL; free(line)) {
+           strappend(extra_info, line);
+           strappend(extra_info, "\n");
+       }
+       afclose(ferr);
+       errfd = -1;
+       rc = 0;
+       while ((wpid = wait(&retstat)) != -1) {
+           if (WIFSIGNALED(retstat)) {
+                   ret = 0;
+                   rc = sig = WTERMSIG(retstat);
+           } else {
+                   sig = 0;
+                   rc = ret = WEXITSTATUS(retstat);
+           }
+           if (rc != 0) {
+                   if (ret == 0) {
+                       strappend(err, "got signal ");
+                       ret = sig;
+                   } else {
+                       strappend(err, "returned ");
+                   }
+                   ap_snprintf(number, sizeof(number), "%d", ret);
+                   strappend(err, number);
+           }
+       }
+       if (rc != 0) {
+           if(extra_info) {
+               fputs(extra_info, stderr);
+               amfree(extra_info);
+           }
+           error("error running mailer %s: %s", MAILER, err);
+       }
+    }
+#endif
+    dbclose();
+    return (server_probs || client_probs);
+}
+
+/* --------------------------------------------------- */
+
+int nslots, backwards, found, got_match, tapedays;
+char *datestamp;
+char *first_match_label = NULL, *first_match = NULL, *found_device = NULL;
+char *label;
+char *searchlabel, *labelstr;
+tape_t *tp;
+FILE *errf;
+
+int scan_init(rc, ns, bk)
+int rc, ns, bk;
+{
+    if(rc)
+       error("could not get changer info: %s", changer_resultstr);
+
+    nslots = ns;
+    backwards = bk;
+
+    return 0;
+}
+
+int taperscan_slot(rc, slotstr, device)
+int rc;
+char *slotstr;
+char *device;
+{
+    char *errstr;
+
+    if(rc == 2) {
+       fprintf(errf, "%s: fatal slot %s: %s\n",
+               get_pname(), slotstr, changer_resultstr);
+       return 1;
+    }
+    else if(rc == 1) {
+       fprintf(errf, "%s: slot %s: %s\n",
+               get_pname(), slotstr, changer_resultstr);
+       return 0;
+    }
+    else {
+       if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
+           fprintf(errf, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
+       } else {
+           /* got an amanda tape */
+           fprintf(errf, "%s: slot %s: date %-8s label %s",
+                   get_pname(), slotstr, datestamp, label);
+           if(searchlabel != NULL
+              && (strcmp(label, FAKE_LABEL) == 0
+                  || strcmp(label, searchlabel) == 0)) {
+               /* it's the one we are looking for, stop here */
+               fprintf(errf, " (exact label match)\n");
+               found_device = newstralloc(found_device, device);
+               found = 1;
+               return 1;
+           }
+           else if(!match(labelstr, label))
+               fprintf(errf, " (no match)\n");
+           else {
+               /* not an exact label match, but a labelstr match */
+               /* check against tape list */
+               tp = lookup_tapelabel(label);
+               if(tp == NULL)
+                   fprintf(errf, " (Not in tapelist)\n");
+               else if(!reusable_tape(tp))
+                   fprintf(errf, " (active tape)\n");
+               else if(got_match == 0 && tp->datestamp == 0) {
+                   got_match = 1;
+                   first_match = newstralloc(first_match, slotstr);
+                   first_match_label = newstralloc(first_match_label, label);
+                   fprintf(errf, " (new tape)\n");
+                   found = 3;
+                   found_device = newstralloc(found_device, device);
+                   return 1;
+               }
+               else if(got_match)
+                   fprintf(errf, " (labelstr match)\n");
+               else {
+                   got_match = 1;
+                   first_match = newstralloc(first_match, slotstr);
+                   first_match_label = newstralloc(first_match_label, label);
+                   fprintf(errf, " (first labelstr match)\n");
+                   if(!backwards || !searchlabel) {
+                       found = 2;
+                       found_device = newstralloc(found_device, device);
+                       return 1;
+                   }
+               }
+           }
+       }
+    }
+    return 0;
+}
+
+char *taper_scan()
+{
+    char *outslot = NULL;
+
+    if((tp = lookup_last_reusable_tape(0)) == NULL)
+       searchlabel = NULL;
+    else
+       searchlabel = tp->label;
+
+    found = 0;
+    got_match = 0;
+
+    changer_find(scan_init, taperscan_slot, searchlabel);
+
+    if(found == 2 || found == 3)
+       searchlabel = first_match_label;
+    else if(!found && got_match) {
+       searchlabel = first_match_label;
+       amfree(found_device);
+       if(changer_loadslot(first_match, &outslot, &found_device) == 0) {
+           found = 1;
+       }
+    } else if(!found) {
+       if(searchlabel) {
+           changer_resultstr = newvstralloc(changer_resultstr,
+                                            "label ", searchlabel,
+                                            " or new tape not found in rack",
+                                            NULL);
+       } else {
+           changer_resultstr = newstralloc(changer_resultstr,
+                                           "new tape not found in rack");
+       }
+    }
+    amfree(outslot);
+
+    return found ? found_device : NULL;
+}
+
+int test_server_pgm(outf, dir, pgm, suid, dumpuid)
+FILE *outf;
+char *dir;
+char *pgm;
+int suid;
+uid_t dumpuid;
+{
+    struct stat statbuf;
+    int pgmbad = 0;
+
+    pgm = vstralloc(dir, "/", pgm, versionsuffix(), NULL);
+    if(stat(pgm, &statbuf) == -1) {
+       fprintf(outf, "ERROR: program %s: does not exist\n",
+               pgm);
+       pgmbad = 1;
+    } else if (!S_ISREG(statbuf.st_mode)) {
+       fprintf(outf, "ERROR: program %s: not a file\n",
+               pgm);
+       pgmbad = 1;
+    } else if (access(pgm, X_OK) == -1) {
+       fprintf(outf, "ERROR: program %s: not executable\n",
+               pgm);
+       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);
+    }
+    amfree(pgm);
+    return pgmbad;
+}
+
+int start_server_check(fd, do_localchk, do_tapechk)
+    int fd;
+{
+    char *errstr, *tapename;
+    generic_fs_stats_t fs;
+    tape_t *tp;
+    FILE *outf;
+    holdingdisk_t *hdp;
+    int pid;
+    int confbad = 0, tapebad = 0, disklow = 0, logbad = 0;
+    int userbad = 0, infobad = 0, indexbad = 0, pgmbad = 0;
+    int testtape = do_tapechk;
+
+    switch(pid = fork()) {
+    case -1: error("could not fork server check: %s", strerror(errno));
+    case 0: break;
+    default:
+       return pid;
+    }
+
+    dup2(fd, 1);
+    dup2(fd, 2);
+
+    set_pname("amcheck-server");
+
+    amfree(msg);
+
+    startclock();
+
+    if((outf = fdopen(fd, "w")) == NULL)
+       error("fdopen %d: %s", fd, strerror(errno));
+    errf = outf;
+
+    fprintf(outf, "Amanda Tape Server Host Check\n");
+    fprintf(outf, "-----------------------------\n");
+
+    /*
+     * Check various server side config file settings.
+     */
+    if(do_localchk) {
+       char *ColumnSpec;
+       char *errstr = NULL;
+       tapetype_t *tp;
+       char *lbl_templ;
+
+       ColumnSpec = getconf_str(CNF_COLUMNSPEC);
+       if(SetColumDataFromString(ColumnData, ColumnSpec, &errstr) < 0) {
+           fprintf(outf, "ERROR: %s\n", errstr);
+           amfree(errstr);
+           confbad = 1;
+       }
+       tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
+       lbl_templ = tp->lbl_templ;
+       if(strcmp(lbl_templ, "") != 0) {
+           if(strchr(lbl_templ, '/') == NULL) {
+               lbl_templ = stralloc2(config_dir, lbl_templ);
+           } else {
+               lbl_templ = stralloc(lbl_templ);
+           }
+           if(access(lbl_templ, R_OK) == -1) {
+               fprintf(outf,
+                       "ERROR: cannot access lbl_templ file %s: %s\n",
+                       lbl_templ,
+                       strerror(errno));
+               confbad = 1;
+           }
+#if !defined(LPRCMD)
+           fprintf(outf, "ERROR: lbl_templ set but no LPRCMD defined, you should reconfigure amanda\n       and make sure it find a lpr or lp command.\n");
+           confbad = 1;
+#endif
+       }
+    }
+
+    /*
+     * Look up the programs used on the server side.
+     */
+    if(do_localchk) {
+       if(access(libexecdir, X_OK) == -1) {
+           fprintf(outf, "ERROR: program dir %s: not accessible\n",
+                   libexecdir);
+           pgmbad = 1;
+       } else {
+           pgmbad = pgmbad \
+                    || test_server_pgm(outf, libexecdir, "planner",
+                                       1, uid_dumpuser);
+           pgmbad = pgmbad \
+                    || test_server_pgm(outf, libexecdir, "dumper",
+                                       1, 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(access(sbindir, X_OK) == -1) {
+           fprintf(outf, "ERROR: program dir %s: not accessible\n",
+                   sbindir);
+           pgmbad = 1;
+       } 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(access(COMPRESS_PATH, X_OK) == -1) {
+           fprintf(outf, "WARNING: %s is not executable, server-compression and indexing will not work\n",
+                   COMPRESS_PATH);
+       }
+    }
+
+    /*
+     * Check that the directory for the tapelist file is writable, as well
+     * as the tapelist file itself (if it already exists).  Also, check for
+     * a "hold" file (just because it is convenient to do it here) and warn
+     * if tapedev is set to the null device.
+     */
+
+    if(do_localchk || do_tapechk) {
+       char *conf_tapelist;
+       char *tapefile;
+       char *tape_dir;
+       char *lastslash;
+       char *holdfile;
+
+       conf_tapelist=getconf_str(CNF_TAPELIST);
+       if (*conf_tapelist == '/') {
+           tapefile = stralloc(conf_tapelist);
+       } else {
+           tapefile = stralloc2(config_dir, conf_tapelist);
+       }
+       /*
+        * XXX There Really Ought to be some error-checking here... dhw
+        */
+       tape_dir = stralloc(tapefile);
+       if ((lastslash = strrchr((const char *)tape_dir, '/')) != NULL) {
+           *lastslash = '\0';
+       /*
+        * else whine Really Loudly about a path with no slashes??!?
+        */
+       }
+       if(access(tape_dir, W_OK) == -1) {
+           fprintf(outf, "ERROR: tapelist dir %s: not writable\n", tape_dir);
+           tapebad = 1;
+       } else if(access(tapefile, F_OK) == 0 && access(tapefile, W_OK) != 0) {
+           fprintf(outf, "ERROR: tape list %s: not writable\n", tapefile);
+           tapebad = 1;
+       } else if(read_tapelist(tapefile)) {
+           fprintf(outf, "ERROR: tape list %s: parse error\n", tapefile);
+           tapebad = 1;
+       }
+       holdfile = vstralloc(config_dir, "/", "hold", NULL);
+       if(access(holdfile, F_OK) != -1) {
+           fprintf(outf, "WARNING: hold file %s exists\n", holdfile);
+       }
+       amfree(tapefile);
+       amfree(tape_dir);
+       amfree(holdfile);
+       tapename = getconf_str(CNF_TAPEDEV);
+       if (strncmp(tapename, "null:", 5) == 0) {
+           fprintf(outf,
+                   "WARNING: tapedev is %s, dumps will be thrown away\n",
+                   tapename);
+           testtape = 0;
+           do_tapechk = 0;
+       }
+    }
+
+    /* check available disk space */
+
+    if(do_localchk) {
+       for(hdp = holdingdisks; hdp != NULL; hdp = hdp->next) {
+           if(get_fs_stats(hdp->diskdir, &fs) == -1) {
+               fprintf(outf, "ERROR: holding disk %s: statfs: %s\n",
+                       hdp->diskdir, strerror(errno));
+               disklow = 1;
+           }
+           else if(access(hdp->diskdir, W_OK) == -1) {
+               fprintf(outf, "ERROR: holding disk %s: not writable: %s\n",
+                       hdp->diskdir, strerror(errno));
+               disklow = 1;
+           }
+           else if(fs.avail == -1) {
+               fprintf(outf,
+                       "WARNING: holding disk %s: available space unknown (%ld KB requested)\n",
+                       hdp->diskdir, (long)hdp->disksize);
+               disklow = 1;
+           }
+           else if(hdp->disksize > 0) {
+               if(fs.avail < hdp->disksize) {
+                   fprintf(outf,
+                           "WARNING: holding disk %s: only %ld KB free (%ld KB requested)\n",
+                           hdp->diskdir, (long)fs.avail, (long)hdp->disksize);
+                   disklow = 1;
+               }
+               else
+                   fprintf(outf,
+                           "Holding disk %s: %ld KB disk space available, that's plenty\n",
+                           hdp->diskdir, fs.avail);
+           }
+           else {
+               if(fs.avail < -hdp->disksize) {
+                   fprintf(outf,
+                           "WARNING: holding disk %s: only %ld KB free, using nothing\n",
+                           hdp->diskdir, fs.avail);
+                   disklow = 1;
+               }
+               else
+                   fprintf(outf,
+                           "Holding disk %s: %ld KB disk space available, using %ld KB\n",
+                           hdp->diskdir, fs.avail, fs.avail + hdp->disksize);
+           }
+       }
+    }
+
+    /* check that the log file is writable if it already exists */
+
+    if(do_localchk) {
+       char *conf_logdir;
+       char *logfile;
+       char *olddir;
+       struct stat stat_old;
+
+       conf_logdir = getconf_str(CNF_LOGDIR);
+       if (*conf_logdir == '/') {
+           conf_logdir = stralloc(conf_logdir);
+       } else {
+           conf_logdir = stralloc2(config_dir, conf_logdir);
+       }
+       logfile = vstralloc(conf_logdir, "/log", NULL);
+
+       if(access(conf_logdir, W_OK) == -1) {
+           fprintf(outf, "ERROR: log dir %s: not writable\n", conf_logdir);
+           logbad = 1;
+       }
+
+       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);
+       }
+
+       olddir = vstralloc(conf_logdir, "/oldlog", NULL);
+       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);
+           }
+           if(access(olddir, W_OK) == -1) {
+               fprintf(outf, "ERROR: oldlog dir %s: not writable\n", olddir);
+           }
+       }
+       else if(lstat(olddir,&stat_old) == 0) {
+           fprintf(outf, "ERROR: oldlog directory \"%s\" is not a directory\n", olddir);
+       }
+
+       if (testtape) {
+           logfile = newvstralloc(logfile, conf_logdir, "/amdump", NULL);
+           if (access(logfile, F_OK) == 0) {
+               testtape = 0;
+               logbad = 1;
+           }
+       }
+
+       amfree(logfile);
+       amfree(conf_logdir);
+    }
+
+    if (testtape) {
+       /* check that the tape is a valid amanda tape */
+
+       tapedays = getconf_int(CNF_TAPECYCLE);
+       labelstr = getconf_str(CNF_LABELSTR);
+       tapename = getconf_str(CNF_TAPEDEV);
+
+       if (!getconf_seen(CNF_TPCHANGER) && getconf_int(CNF_RUNTAPES) != 1) {
+           fprintf(outf,
+                   "WARNING: if a tape changer is not available, runtapes must be set to 1\n");
+       }
+
+       if(changer_init() && (tapename = taper_scan()) == NULL) {
+           fprintf(outf, "ERROR: %s\n", changer_resultstr);
+           tapebad = 1;
+       } else if(tape_access(tapename,F_OK|R_OK|W_OK) == -1) {
+           fprintf(outf, "ERROR: %s: %s\n", tapename, strerror(errno));
+           tapebad = 1;
+       } else if((errstr = tape_rdlabel(tapename, &datestamp, &label)) != NULL) {
+           fprintf(outf, "ERROR: %s: %s\n", tapename, errstr);
+           tapebad = 1;
+       } else if(strcmp(label, FAKE_LABEL) != 0) {
+           if(!match(labelstr, label)) {
+               fprintf(outf, "ERROR: label %s doesn't match labelstr \"%s\"\n",
+                       label, labelstr);
+               tapebad = 1;
+           }
+           else {
+               tp = lookup_tapelabel(label);
+               if(tp == NULL) {
+                   fprintf(outf, "ERROR: label %s match labelstr but it not listed in the tapelist file.\n", label);
+                   tapebad = 1;
+               }
+               else if(tp != NULL && !reusable_tape(tp)) {
+                   fprintf(outf, "ERROR: cannot overwrite active tape %s\n",
+                           label);
+                   tapebad = 1;
+               }
+           }
+
+       }
+
+       if(tapebad) {
+           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");
+       }
+
+       if(!tapebad && overwrite) {
+           if((errstr = tape_writable(tapename)) != NULL) {
+               fprintf(outf,
+                       "ERROR: tape %s label ok, but is not writable\n",
+                       label);
+               tapebad = 1;
+           }
+           else fprintf(outf, "Tape %s is writable\n", label);
+       }
+       else fprintf(outf, "NOTE: skipping tape-writable test\n");
+
+       if(!tapebad)
+           fprintf(outf, "Tape %s label ok\n", label);
+    } 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");
+    } else {
+       fprintf(outf, "NOTE: skipping tape checks\n");
+    }
+
+    /*
+     * See if the information file and index directory for each client
+     * and disk is OK.  Since we may be seeing clients and/or disks for
+     * the first time, these are just warnings, not errors.
+     */
+    if(do_localchk) {
+       char *conf_infofile;
+       char *conf_indexdir;
+       char *hostinfodir = NULL;
+       char *hostindexdir = NULL;
+       char *diskdir = NULL;
+       char *infofile = NULL;
+       struct stat statbuf;
+       disk_t *dp;
+       host_t *hostp;
+       int indexdir_checked = 0;
+       int hostindexdir_checked = 0;
+       char *host;
+       char *disk;
+       int conf_tapecycle, conf_runspercycle;
+
+       conf_tapecycle = getconf_int(CNF_TAPECYCLE);
+       conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
+
+       if(conf_tapecycle <= conf_runspercycle) {
+               fprintf(outf, "WARNING: tapecycle (%d) <= runspercycle (%d).\n",
+                       conf_tapecycle, conf_runspercycle);
+       }
+
+       conf_infofile = stralloc(getconf_str(CNF_INFOFILE));
+       if (*conf_infofile != '/') {
+           char *ci = stralloc2(config_dir, conf_infofile);
+           amfree(conf_infofile);
+           conf_infofile = ci;
+       }
+       conf_indexdir = stralloc(getconf_str(CNF_INDEXDIR));
+       if (*conf_indexdir != '/') {
+           char *ci = stralloc2(config_dir, conf_indexdir);
+           amfree(conf_indexdir);
+           conf_indexdir = ci;
+       }
+#if TEXTDB
+       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");
+           amfree(conf_infofile);
+       } else if (!S_ISDIR(statbuf.st_mode)) {
+           fprintf(outf, "ERROR: info dir %s: not a directory\n", conf_infofile);
+           amfree(conf_infofile);
+           infobad = 1;
+       } else if (access(conf_infofile, W_OK) == -1) {
+           fprintf(outf, "ERROR: info dir %s: not writable\n", conf_infofile);
+           amfree(conf_infofile);
+           infobad = 1;
+       } else {
+           strappend(conf_infofile, "/");
+       }
+#endif
+       while(!empty(*origqp)) {
+           hostp = origqp->head->host;
+           host = sanitise_filename(hostp->hostname);
+#if TEXTDB
+           if(conf_infofile) {
+               hostinfodir = newstralloc2(hostinfodir, conf_infofile, host);
+               if(stat(hostinfodir, &statbuf) == -1) {
+                   fprintf(outf, "NOTE: info dir %s: does not exist\n",
+                           hostinfodir);
+                   amfree(hostinfodir);
+               } else if (!S_ISDIR(statbuf.st_mode)) {
+                   fprintf(outf, "ERROR: info dir %s: not a directory\n",
+                           hostinfodir);
+                   amfree(hostinfodir);
+                   infobad = 1;
+               } else if (access(hostinfodir, W_OK) == -1) {
+                   fprintf(outf, "ERROR: info dir %s: not writable\n",
+                           hostinfodir);
+                   amfree(hostinfodir);
+                   infobad = 1;
+               } else {
+                   strappend(hostinfodir, "/");
+               }
+           }
+#endif
+           for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+               disk = sanitise_filename(dp->name);
+#if TEXTDB
+               if(hostinfodir) {
+                   diskdir = newstralloc2(diskdir, hostinfodir, disk);
+                   infofile = vstralloc(diskdir, "/", "info", NULL);
+                   if(stat(diskdir, &statbuf) == -1) {
+                       fprintf(outf, "NOTE: info dir %s: does not exist\n",
+                               diskdir);
+                   } else if (!S_ISDIR(statbuf.st_mode)) {
+                       fprintf(outf, "ERROR: info dir %s: not a directory\n",
+                               diskdir);
+                       infobad = 1;
+                   } else if (access(diskdir, W_OK) == -1) {
+                       fprintf(outf, "ERROR: info dir %s: not writable\n",
+                               diskdir);
+                       infobad = 1;
+                   } else if(stat(infofile, &statbuf) == -1) {
+                       fprintf(outf, "WARNING: info file %s: does not exist\n",
+                               infofile);
+                   } else if (!S_ISREG(statbuf.st_mode)) {
+                       fprintf(outf, "ERROR: info file %s: not a file\n",
+                               infofile);
+                       infobad = 1;
+                   } else if (access(infofile, R_OK) == -1) {
+                       fprintf(outf, "ERROR: info file %s: not readable\n",
+                               infofile);
+                       infobad = 1;
+                   }
+                   amfree(infofile);
+               }
+#endif
+               if(dp->index) {
+                   if(! indexdir_checked) {
+                       if(stat(conf_indexdir, &statbuf) == -1) {
+                           fprintf(outf, "NOTE: index dir %s: does not exist\n",
+                                   conf_indexdir);
+                           amfree(conf_indexdir);
+                       } else if (!S_ISDIR(statbuf.st_mode)) {
+                           fprintf(outf, "ERROR: index dir %s: not a directory\n",
+                                   conf_indexdir);
+                           amfree(conf_indexdir);
+                           indexbad = 1;
+                       } else if (access(conf_indexdir, W_OK) == -1) {
+                           fprintf(outf, "ERROR: index dir %s: not writable\n",
+                                   conf_indexdir);
+                           amfree(conf_indexdir);
+                           indexbad = 1;
+                       } else {
+                           strappend(conf_indexdir, "/");
+                       }
+                       indexdir_checked = 1;
+                   }
+                   if(conf_indexdir) {
+                       if(! hostindexdir_checked) {
+                           hostindexdir = stralloc2(conf_indexdir, host);
+                           if(stat(hostindexdir, &statbuf) == -1) {
+                               fprintf(outf, "NOTE: index dir %s: does not exist\n",
+                                       hostindexdir);
+                               amfree(hostindexdir);
+                           } else if (!S_ISDIR(statbuf.st_mode)) {
+                               fprintf(outf, "ERROR: index dir %s: not a directory\n",
+                                       hostindexdir);
+                               amfree(hostindexdir);
+                               indexbad = 1;
+                           } else if (access(hostindexdir, W_OK) == -1) {
+                               fprintf(outf, "ERROR: index dir %s: not writable\n",
+                                       hostindexdir);
+                               amfree(hostindexdir);
+                               indexbad = 1;
+                           } else {
+                               strappend(hostindexdir, "/");
+                           }
+                           hostindexdir_checked = 1;
+                       }
+                       if(hostindexdir) {
+                           diskdir = newstralloc2(diskdir, hostindexdir, disk);
+                           if(stat(diskdir, &statbuf) == -1) {
+                               fprintf(outf, "NOTE: index dir %s: does not exist\n",
+                                       diskdir);
+                           } else if (!S_ISDIR(statbuf.st_mode)) {
+                               fprintf(outf, "ERROR: index dir %s: not a directory\n",
+                                       diskdir);
+                               indexbad = 1;
+                           } else if (access(diskdir, W_OK) == -1) {
+                               fprintf(outf, "ERROR: index dir %s: is not writable\n",
+                                       diskdir);
+                               indexbad = 1;
+                           }
+                       }
+                   }
+               }
+               amfree(disk);
+               remove_disk(origqp, dp);
+           }
+           amfree(host);
+           amfree(hostindexdir);
+           hostindexdir_checked = 0;
+       }
+       amfree(diskdir);
+       amfree(hostinfodir);
+       amfree(conf_infofile);
+       amfree(conf_indexdir);
+    }
+
+    amfree(datestamp);
+    amfree(label);
+    amfree(config_dir);
+    amfree(config_name);
+
+    fprintf(outf, "Server check took %s seconds\n", walltime_str(curclock()));
+
+    fflush(outf);
+
+    malloc_size_2 = malloc_inuse(&malloc_hist_2);
+
+    if(malloc_size_1 != malloc_size_2) {
+       malloc_list(fd, malloc_hist_1, malloc_hist_2);
+    }
+
+    exit(userbad \
+        || confbad \
+        || tapebad \
+        || disklow \
+        || logbad \
+        || infobad \
+        || indexbad \
+        || pgmbad);
+    /* NOTREACHED */
+    return 0;
+}
+
+/* --------------------------------------------------- */
+
+int remote_errors;
+FILE *outf;
+int amanda_port;
+
+#ifdef KRB4_SECURITY
+int kamanda_port;
+#endif
+
+static void handle_response P((proto_t *p, pkt_t *pkt));
+
+#define HOST_READY                             ((void *)0)     /* must be 0 */
+#define HOST_ACTIVE                            ((void *)1)
+#define HOST_DONE                              ((void *)2)
+
+#define DISK_READY                             ((void *)0)     /* must be 0 */
+#define DISK_ACTIVE                            ((void *)1)
+#define DISK_DONE                              ((void *)2)
+
+int start_host(hostp)
+    host_t *hostp;
+{
+    disk_t *dp;
+    char *req = NULL;
+    int req_len = 0;
+    int rc;
+    int disk_count;
+    char number[NUM_STR_SIZE];
+
+    if(hostp->up != HOST_READY) {
+       return 0;
+    }
+
+    /*
+     * The first time through here we send a "noop" request.  This will
+     * return the feature list from the client if it supports that.
+     * If it does not, handle_result() will set the feature list to an
+     * empty structure.  In either case, we do the disks on the second
+     * (and subsequent) pass(es).
+     */
+    disk_count = 0;
+    if(hostp->features != NULL) { /* selfcheck service */
+       int has_features = am_has_feature(hostp->features,
+                                         fe_req_options_features);
+       int has_hostname = am_has_feature(hostp->features,
+                                         fe_req_options_hostname);
+       int has_maxdumps = am_has_feature(hostp->features,
+                                         fe_req_options_maxdumps);
+
+       if(!am_has_feature(hostp->features, fe_selfcheck_req) &&
+          !am_has_feature(hostp->features, fe_selfcheck_req_device)) {
+           fprintf(outf,
+                   "ERROR: Client %s does not support selfcheck REQ packet.\n",
+                   hostp->hostname);
+       }
+       if(!am_has_feature(hostp->features, fe_selfcheck_rep)) {
+           fprintf(outf,
+                   "ERROR: Client %s does not support selfcheck REP packet.\n",
+                   hostp->hostname);
+       }
+       if(!am_has_feature(hostp->features, fe_sendsize_req_options) &&
+          !am_has_feature(hostp->features, fe_sendsize_req_no_options) &&
+          !am_has_feature(hostp->features, fe_sendsize_req_device)) {
+           fprintf(outf,
+                   "ERROR: Client %s does not support sendsize REQ packet.\n",
+                   hostp->hostname);
+       }
+       if(!am_has_feature(hostp->features, fe_sendsize_rep)) {
+           fprintf(outf,
+                   "ERROR: Client %s does not support sendsize REP packet.\n",
+                   hostp->hostname);
+       }
+       if(!am_has_feature(hostp->features, fe_sendbackup_req) &&
+          !am_has_feature(hostp->features, fe_sendbackup_req_device)) {
+           fprintf(outf,
+                  "ERROR: Client %s does not support sendbackup REQ packet.\n",
+                  hostp->hostname);
+       }
+       if(!am_has_feature(hostp->features, fe_sendbackup_rep)) {
+           fprintf(outf,
+                  "ERROR: Client %s does not support sendbackup REP packet.\n",
+                  hostp->hostname);
+       }
+
+       ap_snprintf(number, sizeof(number), "%d", hostp->maxdumps);
+       req = vstralloc("SERVICE ", "selfcheck", "\n",
+                       "OPTIONS ",
+                       has_features ? "features=" : "",
+                       has_features ? our_feature_string : "",
+                       has_features ? ";" : "",
+                       has_maxdumps ? "maxdumps=" : "",
+                       has_maxdumps ? number : "",
+                       has_maxdumps ? ";" : "",
+                       has_hostname ? "hostname=" : "",
+                       has_hostname ? hostp->hostname : "",
+                       has_hostname ? ";" : "",
+                       "\n",
+                       NULL);
+
+       req_len = strlen(req);
+       req_len += 128;                         /* room for SECURITY ... */
+       req_len += 256;                         /* room for non-disk answers */
+       for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+           char *l;
+           int l_len;
+           char *o;
+
+           if(dp->todo == 0) continue;
+
+           if(dp->up != DISK_READY) {
+               continue;
+           }
+           o = optionstr(dp, hostp->features, outf);
+
+           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);
+               }
+               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);
+               }
+               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);
+               }
+           }
+           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);
+           }
+           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);
+           }
+           l = vstralloc(dp->program, 
+                         " ",
+                         dp->name,
+                         " ",
+                         dp->device ? dp->device : "",
+                         " 0 OPTIONS |",
+                         o,
+                         "\n",
+                         NULL);
+           l_len = strlen(l);
+           amfree(o);
+           /*
+            * Allow 2X for error response in return packet.
+            */
+           if(req_len + l_len > MAX_DGRAM / 2) {
+               amfree(l);
+               break;
+           }
+           strappend(req, l);
+           req_len += l_len;
+           amfree(l);
+           dp->up = DISK_ACTIVE;
+           disk_count++;
+       }
+
+    }
+    else { /* noop service */
+       req = vstralloc("SERVICE ", "noop", "\n",
+                       "OPTIONS ",
+                       "features=", our_feature_string, ";",
+                       "\n",
+                       NULL);
+       for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+           if(dp->todo == 0) continue;
+
+           if(dp->up != DISK_READY) {
+               continue;
+           }
+           disk_count++;
+       }
+    }
+    if(disk_count == 0) {
+       amfree(req);
+       hostp->up = HOST_DONE;
+       return 0;
+    }
+
+#ifdef KRB4_SECURITY
+    if(hostp->disks->auth == AUTH_KRB4)
+       rc = make_krb_request(hostp->hostname, kamanda_port, req,
+                             hostp, conf_ctimeout, handle_response);
+    else
+#endif
+        rc = make_request(hostp->hostname, amanda_port, req,
+                         hostp, conf_ctimeout, handle_response);
+
+    req = NULL;                                /* do not own this any more */
+
+    if(rc) {
+       /* couldn't resolve hostname */
+       fprintf(outf,
+               "ERROR: %s: could not resolve hostname\n", hostp->hostname);
+       remote_errors++;
+       hostp->up = HOST_DONE;
+    } else {
+       hostp->up = HOST_ACTIVE;
+    }
+    return 1;
+}
+
+int start_client_checks(fd)
+int fd;
+{
+    host_t *hostp;
+    disk_t *dp;
+    int hostcount, pid;
+    struct servent *amandad;
+    int userbad = 0;
+
+    switch(pid = fork()) {
+    case -1: error("could not fork client check: %s", strerror(errno));
+    case 0: break;
+    default:
+       return pid;
+    }
+
+    dup2(fd, 1);
+    dup2(fd, 2);
+
+    set_pname("amcheck-clients");
+
+    startclock();
+
+    if((outf = fdopen(fd, "w")) == NULL)
+       error("fdopen %d: %s", fd, strerror(errno));
+    errf = outf;
+
+    fprintf(outf, "\nAmanda Backup Client Hosts Check\n");
+    fprintf(outf,   "--------------------------------\n");
+
+#ifdef KRB4_SECURITY
+    kerberos_service_init();
+#endif
+
+    proto_init(msg->socket, time(0), 1024);
+
+    /* get remote service port */
+    if((amandad = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL)
+       amanda_port = AMANDA_SERVICE_DEFAULT;
+    else
+       amanda_port = ntohs(amandad->s_port);
+
+#ifdef KRB4_SECURITY
+    if((amandad = getservbyname(KAMANDA_SERVICE_NAME, "udp")) == NULL)
+       kamanda_port = KAMANDA_SERVICE_DEFAULT;
+    else
+       kamanda_port = ntohs(amandad->s_port);
+#endif
+
+    hostcount = remote_errors = 0;
+
+    for(dp = origqp->head; dp != NULL; dp = dp->next) {
+       hostp = dp->host;
+       if(hostp->up == HOST_READY) {
+           if(start_host(hostp) == 1) {
+               hostcount++;
+               check_protocol();
+           }
+       }
+    }
+
+    run_protocol();
+    amfree(msg);
+
+    fprintf(outf,
+     "Client check: %d host%s checked in %s seconds, %d problem%s found\n",
+           hostcount, (hostcount == 1) ? "" : "s",
+           walltime_str(curclock()),
+           remote_errors, (remote_errors == 1) ? "" : "s");
+    fflush(outf);
+
+    amfree(config_dir);
+    amfree(config_name);
+
+    malloc_size_2 = malloc_inuse(&malloc_hist_2);
+
+    if(malloc_size_1 != malloc_size_2) {
+       malloc_list(fd, malloc_hist_1, malloc_hist_2);
+    }
+
+    exit(userbad || remote_errors > 0);
+    /* NOTREACHED */
+    return 0;
+}
+
+static void handle_response(p, pkt)
+proto_t *p;
+pkt_t *pkt;
+{
+    host_t *hostp;
+    disk_t *dp;
+    char *line;
+    char *s;
+    char *t;
+    int ch;
+    int tch;
+
+    hostp = (host_t *) p->datap;
+    hostp->up = HOST_READY;
+
+    if(p->state == S_FAILED && pkt == NULL) {
+       if(p->prevstate == S_REPWAIT) {
+           fprintf(outf,
+                   "WARNING: %s: selfcheck reply timed out.\n",
+                   hostp->hostname);
+       }
+       else {
+           fprintf(outf,
+                   "WARNING: %s: selfcheck request timed out.  Host down?\n",
+                   hostp->hostname);
+       }
+       remote_errors++;
+       hostp->up = HOST_DONE;
+       return;
+    }
+
+#ifdef KRB4_SECURITY
+    if(hostp->disks->auth == AUTH_KRB4 &&
+       !check_mutual_authenticator(host2key(hostp->hostname), pkt, p)) {
+       fprintf(outf, "ERROR: %s [mutual-authentication failed]\n",
+               hostp->hostname);
+       remote_errors++;
+       hostp->up = HOST_DONE;
+       return;
+    }
+#endif
+
+#if 0
+    fprintf(errf, "got %sresponse from %s:\n----\n%s----\n\n",
+           (p->state == S_FAILED) ? "NAK " : "", hostp->hostname, pkt->body);
+#endif
+
+    s = pkt->body;
+    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) {
+#undef sc
+
+#define sc "features="
+           t = strstr(line, sc);
+           if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
+               t += sizeof(sc)-1;
+#undef sc
+               am_release_feature_set(hostp->features);
+               if((hostp->features = am_string_to_feature(t)) == NULL) {
+                   fprintf(outf, "ERROR: %s: bad features value: %s\n",
+                           hostp->hostname, line);
+               }
+           }
+
+           continue;
+       }
+
+#define sc "OK "
+       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+#undef sc
+           continue;
+       }
+
+#define sc "ERROR "
+       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+           t = line + sizeof(sc)-1;
+           tch = t[-1];
+#undef sc
+
+           skip_whitespace(t, tch);
+           /*
+            * If the "error" is that the "noop" service is unknown, it
+            * just means the client is "old" (does not support the service).
+            * We can ignore this.
+            */
+           if(hostp->features == NULL
+              && p->state == S_FAILED
+              && (strcmp(t - 1, "unknown service: noop") == 0
+                  || strcmp(t - 1, "noop: invalid service") == 0)) {
+           } else {
+               fprintf(outf, "ERROR: %s%s: %s\n",
+                       (p->state == S_FAILED) ? "NAK " : "",
+                       hostp->hostname,
+                       t - 1);
+               remote_errors++;
+               hostp->up = HOST_DONE;
+           }
+           continue;
+       }
+
+       fprintf(outf, "ERROR: %s: unknown response: %s\n",
+               hostp->hostname, line);
+       remote_errors++;
+       hostp->up = HOST_DONE;
+    }
+    if(hostp->up == HOST_READY && hostp->features == NULL) {
+       /*
+        * The client does not support the features list, so give it an
+        * empty one.
+        */
+       dbprintf(("%s: no feature set from host %s\n",
+                 debug_prefix_time(NULL), hostp->hostname));
+       hostp->features = am_set_default_feature_set();
+    }
+    for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+       if(dp->up == DISK_ACTIVE) {
+           dp->up = DISK_DONE;
+       }
+    }
+    start_host(hostp);
+}
diff --git a/server-src/amcheckdb.sh.in b/server-src/amcheckdb.sh.in
new file mode 100644 (file)
index 0000000..cd374aa
--- /dev/null
@@ -0,0 +1,86 @@
+#! /bin/sh
+#
+# check tapelist against database and vice versa
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+ConfigDir=@CONFIG_DIR@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+Program=`basename $0`
+
+log () {
+       echo 1>&2 "$@"
+       return 0
+}
+
+Config=$1
+if [ "$Config" = "" ]; then
+       log "usage: ${Program} <config>"
+       exit 1
+fi
+
+#
+# Check if the configuration directory exists.  Make sure that the
+# necessary files can be found, such as amanda.conf and tapelist.
+#
+if [ ! -d ${ConfigDir}/${Config} ]; then
+       log "${Program}: configuration directory ${ConfigDir}/${Config} does not exist."
+       exit 1
+fi
+(cd ${ConfigDir}/${Config} >/dev/null 2>&1) || exit $?
+cd ${ConfigDir}/${Config}
+if [ ! -r amanda.conf ]; then
+       log "${Program}: amanda.conf not found or is not readable in ${ConfigDir}."
+       exit 1
+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`
+if [ ! "$TapeList" ]; then
+       TapeList="$ConfigDir/$Config/tapelist"
+fi
+if [ ! -r $TapeList ]; then
+       log "${Program}: $TapeList not found or is not readable."
+       exit 1
+fi
+
+Amadmin=$sbindir/amadmin$SUF
+
+[ ! -x $Amadmin ] \
+       && echo "$Amadmin not found or not executable" >&2 \
+       && exit 1
+
+$Amadmin $Config export \
+       | grep "^stats: " \
+       | while read LINE; do
+               [ "$LINE" = "" ] && continue
+               set $LINE
+               echo $8
+       done \
+       | sort -u \
+       | while read TAPE; do
+               [ "$TAPE" = "" ] && continue
+               grep " $TAPE " $TapeList 2>/dev/null >/dev/null
+               [ $? != 0 ] \
+                       && echo "Tape $TAPE missing in $TapeList"
+       done
+
+echo "Ready."
+
+exit 0
diff --git a/server-src/amcleanup.sh.in b/server-src/amcleanup.sh.in
new file mode 100644 (file)
index 0000000..5fc55cb
--- /dev/null
@@ -0,0 +1,138 @@
+#!/bin/sh
+#
+# Amanda, The Advanced Maryland Automatic Network Disk Archiver
+# Copyright (c) 1991-1998 University of Maryland at College Park
+# All Rights Reserved.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of U.M. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  U.M. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Author: James da Silva, Systems Design and Analysis Group
+#                         Computer Science Department
+#                         University of Maryland at College Park
+#
+
+#
+# amcleanup.sh - clean up and generate a report after a crash.
+
+# try to hit all the possibilities here
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libexecdir=@libexecdir@
+sbindir=@sbindir@
+
+confdir=@CONFIG_DIR@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = yes; then
+       SUF=-@VERSION@
+else
+       SUF=
+fi
+
+if [ $# -ne 1 ]
+then
+        echo "Usage: amcleanup conf"
+        exit 1
+fi
+
+conf=$1
+if [ ! -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
+logfile=$logdir/log
+errfile=$logdir/amdump
+erramflush=$logdir/amflush
+tapecycle=`amgetconf$SUF tapecycle`
+
+if [ -f $logfile ]; then
+       lognotfound=0
+
+       echo "amcleanup: processing outstanding log file."
+       exec </dev/null >/dev/null 2>&1
+       amreport$SUF $conf
+
+       # Roll the log file to its datestamped name.
+       amlogroll$SUF $conf
+
+       # Trim the index file to those for dumps that still exist.
+       amtrmidx$SUF $conf
+
+else
+       echo "amcleanup: no unprocessed logfile to clean up."
+
+       lognotfound=1
+fi
+
+if [ -f $errfile ]; then
+    # if log was found, this will have been directed to /dev/null,
+    # which is fine.
+    echo "amcleanup: $errfile exists, renaming it."
+
+    # Keep debug log through the tapecycle plus a couple days
+    maxdays=`expr $tapecycle + 2`
+
+    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
+       days=`expr $days + 1`
+    done
+    # Now, renumber the existing log files
+    while [ $days -ge 2 ]; do
+       ndays=`expr $days - 1`
+       mv $errfile.$ndays $errfile.$days
+       days=$ndays
+    done
+    mv $errfile $errfile.1
+fi
+
+if [ -f $erramflush ]; then
+    # if log was found, this will have been directed to /dev/null,
+    # which is fine.
+    echo "amcleanup: $erramflush exists, renaming it."
+
+    # Keep debug log through the tapecycle plus a couple days
+    maxdays=`expr $tapecycle + 2`
+
+    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
+       days=`expr $days + 1`
+    done
+    # Now, renumber the existing log files
+    while [ $days -ge 2 ]; do
+       ndays=`expr $days - 1`
+       mv $erramflush.$ndays $erramflush.$days
+       days=$ndays
+    done
+    mv $erramflush $erramflush.1
+fi
+
+$libexecdir/amcleanupdisk $conf
+
+exit $lognotfound
diff --git a/server-src/amcleanupdisk.c b/server-src/amcleanupdisk.c
new file mode 100644 (file)
index 0000000..657ad01
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * 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: amcleanupdisk.c,v 1.1.2.6.4.3.2.2 2002/11/05 01:59:23 martinea Exp $
+ */
+#include "amanda.h"
+
+#include "conffile.h"
+#include "diskfile.h"
+#include "clock.h"
+#include "version.h"
+#include "holding.h"
+#include "infofile.h"
+#include "server_util.h"
+
+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;
+{
+    struct passwd *pw;
+    char *dumpuser;
+    int fd;
+    disklist_t *diskqp;
+    char *conffile;
+    char *conf_diskfile;
+    char *conf_infofile;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amcleanupdisk");
+
+    if(main_argc != 2) {
+       error("Usage: amcleanupdisk%s <confdir>", versionsuffix());
+    }
+
+    config_name = main_argv[1];
+
+    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);
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((diskqp = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist %s", conf_diskfile);
+    }
+    amfree(conf_diskfile);
+    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)) {
+       error("could not open info db \"%s\"", conf_infofile);
+    }
+    amfree(conf_infofile);
+
+    datestamp = construct_datestamp(NULL);
+
+    dumpuser = getconf_str(CNF_DUMPUSER);
+    if((pw = getpwnam(dumpuser)) == NULL) {
+       error("dumpuser %s not found in password file", dumpuser);
+    }
+    if(pw->pw_uid != getuid()) {
+       error("must run amcleanupdisk as user %s", dumpuser);
+    }
+
+    holding_list = pick_all_datestamp(1);
+
+    check_disks();
+
+    close_infofile();
+
+    free_sl(holding_list);
+    holding_list = NULL;
+    amfree(config_dir);
+    return 0;
+}
+
+
+void check_holdingdisk(diskdir, datestamp)
+char *diskdir, *datestamp;
+{
+    DIR *workdir;
+    struct dirent *entry;
+    char *dirname = NULL;
+    char *tmpname = NULL;
+    char *destname = NULL;
+    char *hostname = NULL;
+    char *diskname = NULL;
+    disk_t *dp;
+    filetype_t filetype;
+    info_t info;
+    int level;
+    int dl, l;
+
+    dirname = vstralloc(diskdir, "/", datestamp, NULL);
+    dl = strlen(dirname);
+
+    if((workdir = opendir(dirname)) == NULL) {
+       amfree(dirname);
+       return;
+    }
+
+    while((entry = readdir(workdir)) != NULL) {
+       if(is_dot_or_dotdot(entry->d_name)) {
+           continue;
+       }
+
+       if((l = strlen(entry->d_name)) < 7 ) {
+           continue;
+       }
+
+       if(strncmp(&entry->d_name[l-4],".tmp",4) != 0) {
+           continue;
+       }
+
+       tmpname = newvstralloc(tmpname,
+                              dirname, "/", entry->d_name,
+                              NULL);
+
+       destname = newstralloc(destname, tmpname);
+       destname[dl + 1 + l - 4] = '\0';
+
+       amfree(hostname);
+       amfree(diskname);
+       filetype = get_amanda_names(tmpname, &hostname, &diskname, &level);
+       if(filetype != F_DUMPFILE) {
+           continue;
+       }
+
+       dp = lookup_disk(hostname, diskname);
+
+       if (dp == NULL) {
+           continue;
+       }
+
+       if(level < 0 || level > 9) {
+           continue;
+       }
+
+       if(rename_tmp_holding(destname, 0)) {
+           get_info(dp->host->hostname, dp->name, &info);
+           info.command &= ~FORCE_BUMP;
+           info.command |= FORCE_NO_BUMP;
+           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));
+           }
+       } else {
+           fprintf(stderr,"rename_tmp_holding(%s) failed\n", destname);
+       }
+    }
+    closedir(workdir);
+
+    /* try to zap the potentially empty working dir */
+    /* ignore any errors -- it either works or it doesn't */
+    (void) rmdir(dirname);
+
+    amfree(diskname);
+    amfree(hostname);
+    amfree(destname);
+    amfree(dirname);
+}
+
+
+void check_disks()
+{
+    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);
+    }
+}
diff --git a/server-src/amdump.sh.in b/server-src/amdump.sh.in
new file mode 100644 (file)
index 0000000..ce56b8f
--- /dev/null
@@ -0,0 +1,131 @@
+#!/bin/sh
+#
+# Amanda, The Advanced Maryland Automatic Network Disk Archiver
+# Copyright (c) 1991-1998 University of Maryland at College Park
+# All Rights Reserved.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of U.M. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  U.M. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+# OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+# Author: James da Silva, Systems Design and Analysis Group
+#                         Computer Science Department
+#                         University of Maryland at College Park
+#
+
+#
+# amdump: Manage running one night's Amanda dump run.
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+confdir=@CONFIG_DIR@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+conf=$1
+if [ ! -d $confdir/$conf ]; then
+    echo "amdump$SUF: could not find directory $confdir/$conf"
+    exit 1
+fi
+
+cd $confdir/$conf || exit 1
+
+logdir=`amgetconf$SUF $conf logdir`
+[ $? -ne 0 ]  && exit 1
+errfile=$logdir/amdump
+tapecycle=`amgetconf$SUF $conf tapecycle`
+[ $? -ne 0 ]  && exit 1
+dumpuser=`amgetconf$SUF $conf dumpuser`
+[ $? -ne 0 ]  && exit 1
+
+runuser=`{ whoami ; } 2>/dev/null`
+if [ $? -ne 0 ]; then
+       idinfo=`{ id ; } 2>/dev/null`
+       if [ $? -ne 0 ]; then
+               runuser=${LOGNAME:-"??unknown??"}
+       else
+               runuser=`echo $idinfo | sed -e 's/).*//' -e 's/^.*(//'`
+       fi
+fi
+
+if [ $runuser != $dumpuser ]; then
+       echo "amdump: must be run as user $dumpuser, not $runuser"
+       exit 1
+fi
+
+if test -f hold; then
+       echo "amdump: waiting for hold file to be removed" >&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
+       exit 1
+fi
+
+umask 077
+
+# Plan and drive the dumps.
+exec </dev/null >$errfile 2>&1
+echo "amdump: start at `date`"
+echo "amdump: datestamp `date +%Y%m%d`"
+$libexecdir/planner$SUF "$@" | $libexecdir/driver$SUF $conf
+echo "amdump: end at `date`"
+
+# Send out a report on the dumps.
+exec </dev/null >/dev/null 2>&1
+$sbindir/amreport$SUF $conf
+
+# Roll the log file to its datestamped name.
+$libexecdir/amlogroll$SUF $conf
+
+# Keep a debug log through the tapecycle plus a couple of days.
+maxdays=`expr $tapecycle + 2`
+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
+       days=`expr $days + 1`
+done
+# Now, renumber the existing log files
+while [ $days -ge 2 ]; do
+       ndays=`expr $days - 1`
+       mv $errfile.$ndays $errfile.$days
+       days=$ndays
+done
+mv $errfile $errfile.1
+
+# Trim the log file to those for dumps that still exist.
+$libexecdir/amtrmlog$SUF $conf
+
+# Trim the index file to those for dumps that still exist.
+$libexecdir/amtrmidx$SUF $conf
+
+exit 0
diff --git a/server-src/amflush.c b/server-src/amflush.c
new file mode 100644 (file)
index 0000000..73ff030
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * 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: amflush.c,v 1.41.2.13.4.6.2.10 2004/04/23 11:44:57 martinea Exp $
+ *
+ * write files from work directory onto tape
+ */
+#include "amanda.h"
+
+#include "conffile.h"
+#include "diskfile.h"
+#include "tapefile.h"
+#include "logfile.h"
+#include "clock.h"
+#include "version.h"
+#include "holding.h"
+#include "driverio.h"
+#include "server_util.h"
+
+static char *conf_logdir;
+FILE *driver_stream;
+char *driver_program;
+char *reporter_program;
+char *logroll_program;
+char *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));
+
+
+int main(main_argc, main_argv)
+int main_argc;
+char **main_argv;
+{
+    int foreground;
+    int batch;
+    int redirect;
+    struct passwd *pw;
+    char *dumpuser;
+    char **datearg = NULL;
+    int nb_datearg = 0;
+    int fd;
+    char *conffile;
+    char *conf_diskfile;
+    char *conf_tapelist;
+    char *conf_logfile;
+    disklist_t *diskqp;
+    disk_t *dp;
+    pid_t pid, driver_pid, reporter_pid;
+    amwait_t exitcode;
+    int opt;
+    dumpfile_t file;
+    sl_t *holding_list=NULL;
+    sle_t *holding_file;
+    int driver_pipe[2];
+    char date_string[100];
+    time_t today;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amflush");
+
+    signal(SIGPIPE, SIG_IGN);
+
+    erroutput_type = ERR_INTERACTIVE;
+    foreground = 0;
+    batch = 0;
+    redirect = 1;
+
+    /* process arguments */
+
+    while((opt = getopt(main_argc, main_argv, "bfsD:")) != EOF) {
+       switch(opt) {
+       case 'b': batch = 1;
+                 break;
+       case 'f': foreground = 1;
+                 break;
+       case 's': redirect = 0;
+                 break;
+       case 'D': if (datearg == NULL)
+                       datearg = alloc(21*sizeof(char *));
+                 if(nb_datearg == 20) {
+                     fprintf(stderr,"maximum of 20 -D arguments.\n");
+                     exit(1);
+                 }
+                 datearg[nb_datearg++] = stralloc(optarg);
+                 datearg[nb_datearg] = NULL;
+                 break;
+       }
+    }
+    if(!foreground && !redirect) {
+       fprintf(stderr,"Can't redirect to stdout/stderr if not in forground.\n");
+       exit(1);
+    }
+
+    main_argc -= optind, main_argv += optind;
+
+    if(main_argc < 1) {
+       error("Usage: amflush%s [-b] [-f] [-s] [-D date]* <confdir> [host [disk]* ]*", versionsuffix());
+    }
+
+    config_name = main_argv[0];
+
+    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);
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((diskqp = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not read disklist file \"%s\"", conf_diskfile);
+    }
+    match_disklist(diskqp, main_argc-1, main_argv+1);
+    amfree(conf_diskfile);
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+    amfree(conf_tapelist);
+
+    datestamp = construct_datestamp(NULL);
+
+    dumpuser = getconf_str(CNF_DUMPUSER);
+    if((pw = getpwnam(dumpuser)) == NULL)
+       error("dumpuser %s not found in password file", dumpuser);
+    if(pw->pw_uid != getuid())
+       error("must run amflush as user %s", dumpuser);
+
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+       conf_logdir = stralloc(conf_logdir);
+    } else {
+       conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    conf_logfile = vstralloc(conf_logdir, "/log", NULL);
+    if (access(conf_logfile, F_OK) == 0) {
+       error("%s exists: amdump or amflush is already running, or you must run amcleanup", conf_logfile);
+    }
+    amfree(conf_logfile);
+    driver_program = vstralloc(libexecdir, "/", "driver", versionsuffix(),
+                                NULL);
+    reporter_program = vstralloc(sbindir, "/", "amreport", versionsuffix(),
+                                NULL);
+    logroll_program = vstralloc(libexecdir, "/", "amlogroll", versionsuffix(),
+                               NULL);
+
+    if(datearg) {
+       sle_t *dir, *next_dir;
+       int i, ok;
+
+       datestamp_list = pick_all_datestamp(1);
+       for(dir = datestamp_list->first; dir != NULL;) {
+           next_dir = dir->next;
+           ok = 0;
+           for(i=0; i<nb_datearg && ok==0; i++) {
+               ok = match_datestamp(datearg[i], dir->name);
+           }
+           if(ok == 0) { /* remove dir */
+               remove_sl(datestamp_list, dir);
+           }
+           dir = next_dir;
+       }
+    }
+    else {
+       if(batch) {
+           datestamp_list = pick_all_datestamp(1);
+       }
+       else {
+           datestamp_list = pick_datestamp(1);
+       }
+    }
+
+    if(is_empty_sl(datestamp_list)) {
+       printf("Could not find any Amanda directories to flush.\n");
+       exit(1);
+    }
+
+    if(!batch) confirm();
+
+    for(dp = diskqp->head; dp != NULL; dp = dp->next) {
+       if(dp->todo)
+           log_add(L_DISK, "%s %s", dp->host->hostname, dp->name);
+    }
+
+    if(!foreground) { /* write it before redirecting stdout */
+       puts("Running in background, you can log off now.");
+       puts("You'll get mail when amflush is finished.");
+    }
+
+    if(redirect) redirect_stderr();
+
+    if(!foreground) detach();
+
+    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));
+    fprintf(stderr, "amflush: start at %s\n", date_string);
+    fprintf(stderr, "amflush: datestamp %s\n", datestamp);
+    log_add(L_START, "date %s", datestamp);
+
+    /* START DRIVER */
+    if(pipe(driver_pipe) == -1) {
+       error("error [opening pipe to driver: %s]", strerror(errno));
+    }
+    if((driver_pid = fork()) == 0) {
+       /*
+        * This is the child process.
+        */
+       dup2(driver_pipe[0], 0);
+       close(driver_pipe[1]);
+       execle(driver_program,
+              "driver", config_name, "nodump", (char *)0,
+              safe_env());
+       error("cannot exec %s: %s", driver_program, strerror(errno));
+    } else if(driver_pid == -1) {
+       error("cannot fork for %s: %s", driver_program, strerror(errno));
+    }
+    driver_stream = fdopen(driver_pipe[1], "w");
+
+    holding_list = get_flush(datestamp_list, NULL, 1, 0);
+    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->todo == 0) continue;
+
+       fprintf(stderr,
+               "FLUSH %s %s %s %d %s\n",
+               file.name,
+               file.disk,
+               file.datestamp,
+               file.dumplevel,
+               holding_file->name);
+       fprintf(driver_stream,
+               "FLUSH %s %s %s %d %s\n",
+               file.name,
+               file.disk,
+               file.datestamp,
+               file.dumplevel,
+               holding_file->name);
+    }
+    fprintf(stderr, "ENDFLUSH\n"); fflush(stderr);
+    fprintf(driver_stream, "ENDFLUSH\n"); fflush(driver_stream);
+    fclose(driver_stream);
+
+    /* WAIT DRIVER */
+    while(1) {
+       if((pid = wait(&exitcode)) == -1) {
+           if(errno == EINTR) {
+               continue;
+           } else {
+               error("wait for %s: %s", driver_program, strerror(errno));
+           }
+       } else if (pid == driver_pid) {
+           break;
+       }
+    }
+
+    free_sl(datestamp_list);
+    datestamp_list = NULL;
+    free_sl(holding_list);
+    holding_list = NULL;
+
+    if(redirect) { /* rename errfile */
+       char *errfile, *errfilex, *nerrfilex, number[100];
+       int tapecycle;
+       int maxdays, days;
+               
+       struct stat stat_buf;
+
+       errfile = vstralloc(conf_logdir, "/amflush", NULL);
+       errfilex = NULL;
+       nerrfilex = NULL;
+       tapecycle = getconf_int(CNF_TAPECYCLE);
+       maxdays = tapecycle + 2;
+       days = 1;
+       /* First, find out the last existing errfile,           */
+       /* to avoid ``infinite'' loops if tapecycle is infinite */
+
+       ap_snprintf(number,100,"%d",days);
+       errfilex = newvstralloc(errfilex, errfile, ".", number, NULL);
+       while ( days < maxdays && stat(errfilex,&stat_buf)==0) {
+           days++;
+           ap_snprintf(number,100,"%d",days);
+           errfilex = newvstralloc(errfilex, errfile, ".", number, NULL);
+       }
+       ap_snprintf(number,100,"%d",days);
+       errfilex = newvstralloc(errfilex, errfile, ".", number, NULL);
+       nerrfilex = NULL;
+       while (days > 1) {
+           amfree(nerrfilex);
+           nerrfilex = errfilex;
+           days--;
+           ap_snprintf(number,100,"%d",days);
+           errfilex = vstralloc(errfile, ".", number, NULL);
+           if (rename(errfilex, nerrfilex) != 0) {
+               error("cannot rename \"%s\" to \"%s\": %s",
+                     errfilex, nerrfilex, strerror(errno));
+           }
+       }
+       errfilex = newvstralloc(errfilex, errfile, ".1", NULL);
+       if (rename(errfile,errfilex) != 0) {
+           error("cannot rename \"%s\" to \"%s\": %s",
+                 errfilex, nerrfilex, strerror(errno));
+       }
+       amfree(errfile);
+       amfree(errfilex);
+       amfree(nerrfilex);
+    }
+
+    /*
+     * Have amreport generate report and send mail.  Note that we do
+     * not bother checking the exit status.  If it does not work, it
+     * can be rerun.
+     */
+
+    if((reporter_pid = fork()) == 0) {
+       /*
+        * This is the child process.
+        */
+       execle(reporter_program,
+              "amreport", config_name, (char *)0,
+              safe_env());
+       error("cannot exec %s: %s", reporter_program, strerror(errno));
+    } else if(reporter_pid == -1) {
+       error("cannot fork for %s: %s", reporter_program, strerror(errno));
+    }
+    while(1) {
+       if((pid = wait(&exitcode)) == -1) {
+           if(errno == EINTR) {
+               continue;
+           } else {
+               error("wait for %s: %s", reporter_program, strerror(errno));
+           }
+       } else if (pid == reporter_pid) {
+           break;
+       }
+    }
+
+    /*
+     * 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));
+    return 0;                          /* keep the compiler happy */
+}
+
+
+int get_letter_from_user()
+{
+    int r = '\0';
+    int ch;
+
+    fflush(stdout); fflush(stderr);
+    while((ch = getchar()) != EOF && ch != '\n' && isspace(ch)) {}
+    if(ch == '\n') {
+       r = '\0';
+    } else if (ch != EOF) {
+       r = ch;
+       if(islower(r)) r = toupper(r);
+       while((ch = getchar()) != EOF && ch != '\n') {}
+    } else {
+       r = ch;
+       clearerr(stdin);
+    }
+    return r;
+}
+
+
+void confirm()
+/* confirm before detaching and running */
+{
+    tape_t *tp;
+    char *tpchanger;
+    sle_t *dir;
+    int ch;
+    char *extra;
+
+    printf("\nToday is: %s\n",datestamp);
+    printf("Flushing dumps in");
+    extra = "";
+    for(dir = datestamp_list->first; dir != NULL; dir = dir->next) {
+       printf("%s %s", extra, dir->name);
+       extra = ",";
+    }
+    tpchanger = getconf_str(CNF_TPCHANGER);
+    if(*tpchanger != '\0') {
+       printf(" using tape changer \"%s\".\n", tpchanger);
+    } else {
+       printf(" to tape drive \"%s\".\n", getconf_str(CNF_TAPEDEV));
+    }
+
+    printf("Expecting ");
+    tp = lookup_last_reusable_tape(0);
+    if(tp != NULL) printf("tape %s or ", tp->label);
+    printf("a new tape.");
+    tp = lookup_tapepos(1);
+    if(tp != NULL) printf("  (The last dumps were to tape %s)", tp->label);
+
+    while (1) {
+       printf("\nAre you sure you want to do this [yN]? ");
+       if((ch = get_letter_from_user()) == 'Y') {
+           return;
+       } else if (ch == 'N' || ch == '\0' || ch == EOF) {
+           if (ch == EOF) {
+               putchar('\n');
+           }
+           break;
+       }
+    }
+
+    printf("Ok, quitting.  Run amflush again when you are ready.\n");
+    exit(1);
+}
+
+void redirect_stderr()
+{
+    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)
+       error("could not open %s: %s", errfile, strerror(errno));
+    dup2(fderr,1);
+    dup2(fderr,2);
+    aclose(fderr);
+    amfree(errfile);
+}
+
+void detach()
+{
+    int fd;
+
+    fflush(stdout); fflush(stderr);
+    if((fd = open("/dev/null", O_RDWR, 0666)) == -1)
+       error("could not open /dev/null: %s", strerror(errno));
+
+    dup2(fd,0);
+    aclose(fd);
+
+    switch(fork()) {
+    case -1: error("could not fork: %s", strerror(errno));
+    case 0:
+       setsid();
+       return;
+    }
+
+    exit(0);
+}
+
+
diff --git a/server-src/amfreetapes.sh.in b/server-src/amfreetapes.sh.in
new file mode 100644 (file)
index 0000000..98b78cc
--- /dev/null
@@ -0,0 +1,94 @@
+#! /bin/sh
+#
+# ICEM internal :-)
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+ConfigDir=@CONFIG_DIR@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+Program=`basename $0`
+
+log () {
+       echo 1>&2 "$@"
+       return 0
+}
+
+Config=$1
+if [ "$Config" = "" ]; then
+       log "usage: ${Program} <config> <volume header>"
+       exit 1
+fi
+VOLHEADER=$2
+if [ "$VOLHEADER" = "" ]; then
+       log "usage: ${Program} <config> <volume header>"
+       exit 1
+fi
+
+#
+# Check if the configuration directory exists.  Make sure that the
+# necessary files can be found, such as amanda.conf and tapelist.
+#
+if [ ! -d ${ConfigDir}/${Config} ]; then
+       log "${Program}: configuration directory ${ConfigDir}/${Config} does not exist."
+       exit 1
+fi
+(cd ${ConfigDir}/${Config} >/dev/null 2>&1) || exit $?
+cd ${ConfigDir}/${Config}
+if [ ! -r amanda.conf ]; then
+       log "${Program}: amanda.conf not found or is not readable in ${ConfigDir}."
+       exit 1
+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`
+if [ ! "$TapeList" ]; then
+       TapeList="$ConfigDir/$Config/tapelist"
+fi
+if [ ! -r $TapeList ]; then
+       log "${Program}: $TapeList not found or is not readable."
+       exit 1
+fi
+
+AllTapeList="${TapeList}.all"
+
+[ ! -f $AllTapeList ] \
+       && echo "no tapelist $AllTapeList found" >&2 \
+       && cat $TapeList | sed 's/^.* //' | sort -u > $AllTapeList \
+       && echo "$AllTapeList created" >&2
+
+cat $TapeList | sed 's/^.* //' > $AllTapeList.n
+cat $AllTapeList >> $AllTapeList.n
+sort -u $AllTapeList.n > $AllTapeList && rm -f $AllTapeList.n
+
+MAXTAPE=`cat $AllTapeList | sed "s/^$VOLHEADER//" | sort -n | tail -1`
+NEXTTAPE=`expr $MAXTAPE + 1`
+echo "last Tape is ${VOLHEADER}${MAXTAPE}" >&2
+
+I=1
+while [ $I -le $MAXTAPE ]; do
+       WRITTEN=`grep "${VOLHEADER}${I}\$" $TapeList`
+       EXISTS=`grep "${VOLHEADER}${I}\$" $AllTapeList`
+       if [ "$EXISTS" = "" -a "$WRITTEN" = "" ]; then
+               echo "missing tape ${VOLHEADER}${I}" >&2
+               echo "${VOLHEADER}${I}" >> $AllTapeList \
+               && echo "added ${VOLHEADER}${I} to $AllTapeList" >&2
+       elif [ "$EXISTS" = "" -a "$WRITTEN" != "" ]; then
+               echo "tape written, but not existing: ${VOLHEADER}${I}" >&2
+       elif [ "$EXISTS" != "" -a "$WRITTEN" = "" ]; then
+               echo "free tape: ${VOLHEADER}${I}" >&2
+       fi
+       I=`expr $I + 1`
+done
+
+echo "next tape is ${VOLHEADER}${NEXTTAPE}" >&2
+
+exit 0
diff --git a/server-src/amindex.c b/server-src/amindex.c
new file mode 100644 (file)
index 0000000..9944b1f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: amindex.c,v 1.10.4.2.4.1 2001/09/01 03:35:17 jrjackson Exp $
+ *
+ * index control
+ */
+
+#include "conffile.h"
+#include "amindex.h"
+
+char *getindexfname(host, disk, date, level)
+char *host, *disk, *date;
+int level;
+{
+  char *conf_indexdir;
+  char *buf;
+  char level_str[NUM_STR_SIZE];
+  char datebuf[8 + 1];
+  char *dc = NULL;
+  char *pc;
+  int ch;
+
+  if (date != NULL) {
+    dc = date;
+    pc = datebuf;
+    while (pc < datebuf + sizeof (datebuf)) {
+      if ((*pc++ = ch = *dc++) == '\0') {
+        break;
+      } else if (! isdigit (ch)) {
+        pc--;
+      }
+    }
+    datebuf[sizeof(datebuf)-1] = '\0';
+    dc = datebuf;
+
+    ap_snprintf(level_str, sizeof(level_str), "%d", level);
+  }
+
+  host = sanitise_filename(host);
+  if (disk != NULL) {
+    disk = sanitise_filename(disk);
+  }
+
+  conf_indexdir = getconf_str(CNF_INDEXDIR);
+  if (*conf_indexdir == '/') {
+    conf_indexdir = stralloc(conf_indexdir);
+  } else {
+    conf_indexdir = stralloc2(config_dir, conf_indexdir);
+  }
+  /*
+   * Note: vstralloc() will stop at the first NULL, which might be
+   * "disk" or "dc" (datebuf) rather than the full file name.
+   */
+  buf = vstralloc(conf_indexdir, "/",
+                 host, "/",
+                 disk, "/",
+                 dc, "_",
+                 level_str, COMPRESS_SUFFIX,
+                 NULL);
+
+  amfree(conf_indexdir);
+  amfree(host);
+  amfree(disk);
+
+  return buf;
+}
diff --git a/server-src/amindex.h b/server-src/amindex.h
new file mode 100644 (file)
index 0000000..0814561
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: amindex.h,v 1.5.4.2 1999/09/08 23:27:30 jrj Exp $
+ *
+ * headers for index control
+ */
+#ifndef AMINDEX_H
+#define AMINDEX_H
+
+#include "amanda.h"
+#include "conffile.h"
+
+char *getindexfname P((char *host, char *disk, char *date, int level));
+
+#endif /* AMINDEX_H */
diff --git a/server-src/amindexd.c b/server-src/amindexd.c
new file mode 100644 (file)
index 0000000..38079b0
--- /dev/null
@@ -0,0 +1,1169 @@
+/*
+ * 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: amindexd.c,v 1.39.2.11.4.4.2.13 2003/10/27 18:33:03 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
+ * started as a daemon because it is not often used
+ */
+
+/*
+** Notes:
+** - this server will do very little until it knows what Amanda config it
+**   is to use.  Setting the config has the side effect of changing to the
+**   index directory.
+** - XXX - I'm pretty sure the config directory name should have '/'s stripped
+**   from it.  It is given to us by an unknown person via the network.
+*/
+
+#include "amanda.h"
+#include "conffile.h"
+#include "diskfile.h"
+#include "arglist.h"
+#include "clock.h"
+#include "dgram.h"
+#include "version.h"
+#include "protocol.h"
+#include "amindex.h"
+#include "disk_history.h"
+#include "list_dir.h"
+#include "logfile.h"
+#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 <grp.h>
+
+typedef struct REMOVE_ITEM
+{
+    char *filename;
+    struct REMOVE_ITEM *next;
+} 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 amindexd_debug = 0;
+
+static REMOVE_ITEM *uncompress_remove = NULL;
+                                       /* uncompressed files to remove */
+
+static am_feature_t *our_features = NULL;
+static am_feature_t *their_features = NULL;
+
+static void reply P((int n, char * fmt, ...))
+    __attribute__ ((format (printf, 2, 3)));
+static void lreply P((int n, char * fmt, ...))
+    __attribute__ ((format (printf, 2, 3)));
+static void fast_lreply P((int n, char * fmt, ...))
+    __attribute__ ((format (printf, 2, 3)));
+
+REMOVE_ITEM *remove_files(remove)
+REMOVE_ITEM *remove;
+{
+    REMOVE_ITEM *prev;
+
+    while(remove) {
+       dbprintf(("%s: removing index file: %s\n",
+                 debug_prefix_time(NULL), remove->filename));
+       unlink(remove->filename);
+       amfree(remove->filename);
+       prev = remove;
+       remove = remove->next;
+       amfree(prev);
+    }
+    return remove;
+}
+
+char *uncompress_file(filename_gz, emsg)
+char *filename_gz;
+char **emsg;
+{
+    char *cmd = NULL;
+    char *filename = NULL;
+    struct stat stat_filename;
+    int result;
+    int len;
+
+    filename = stralloc(filename_gz);
+    len = strlen(filename);
+    if(len > 3 && strcmp(&(filename[len-3]),".gz")==0) {
+       filename[len-3]='\0';
+    } else if(len > 2 && strcmp(&(filename[len-2]),".Z")==0) {
+       filename[len-2]='\0';
+    }
+
+    /* uncompress the file */
+    result=stat(filename,&stat_filename);
+    if(result==-1 && errno==ENOENT) {          /* file does not exist */
+       REMOVE_ITEM *remove_file;
+       cmd = vstralloc(UNCOMPRESS_PATH,
+#ifdef UNCOMPRESS_OPT
+                       " ", UNCOMPRESS_OPT,
+#endif
+                       " \'", filename_gz, "\'",
+                       " 2>/dev/null",
+                       " | 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);
+           unlink(filename);
+           errno = -1;
+           amfree(filename);
+           amfree(cmd);
+           return NULL;
+       }
+
+       /* add at beginning */
+       remove_file = (REMOVE_ITEM *)alloc(sizeof(REMOVE_ITEM));
+       remove_file->filename = stralloc(filename);
+       remove_file->next = uncompress_remove;
+       uncompress_remove = remove_file;
+    } else if(!S_ISREG((stat_filename.st_mode))) {
+           amfree(*emsg);
+           *emsg = vstralloc("\"", filename, "\" is not a regular file", NULL);
+           errno = -1;
+           amfree(filename);
+           amfree(cmd);
+           return NULL;
+    } else {
+       /* already uncompressed */
+    }
+    amfree(cmd);
+    return filename;
+}
+
+/* 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;
+{
+    char *line = NULL;
+    char *old_line = NULL;
+    char *filename = NULL;
+    char *filename_gz;
+    char *dir_slash = NULL;
+    FILE *fp;
+    char *s;
+    int ch;
+    int len_dir_slash;
+
+    if (strcmp(dir, "/") == 0) {
+       dir_slash = stralloc(dir);
+    } else {
+       dir_slash = stralloc2(dir, "/");
+    }
+
+    filename_gz = getindexfname(dump_hostname, disk_name, dump_item->date,
+                               dump_item->level);
+    if((filename = uncompress_file(filename_gz, emsg)) == NULL) {
+       amfree(filename_gz);
+       amfree(dir_slash);
+       return -1;
+    }
+    amfree(filename_gz);
+
+    if((fp = fopen(filename,"r"))==0) {
+       amfree(*emsg);
+       *emsg = stralloc(strerror(errno));
+       amfree(dir_slash);
+       return -1;
+    }
+
+    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 == '/') {
+                   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;
+           }
+       }
+    }
+    afclose(fp);
+    amfree(old_line);
+    amfree(line);
+    amfree(filename);
+    amfree(dir_slash);
+    return 0;
+}
+
+/* send a 1 line reply to the client */
+printf_arglist_function1(static void reply, int, n, char *, fmt)
+{
+    va_list args;
+    char buf[STR_SIZE];
+
+    arglist_start(args, fmt);
+    ap_snprintf(buf, sizeof(buf), "%03d ", n);
+    ap_vsnprintf(buf+4, sizeof(buf)-4, fmt, args);
+    arglist_end(args);
+
+    if (printf("%s\r\n", buf) < 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 (fflush(stdout) != 0)
+    {
+       dbprintf(("%s: ! error %d (%s) in fflush\n",
+                 debug_prefix_time(NULL), errno, strerror(errno)));
+       uncompress_remove = remove_files(uncompress_remove);
+       exit(1);
+    }
+    dbprintf(("%s: < %s\n", debug_prefix_time(NULL), buf));
+}
+
+/* send one line of a multi-line response */
+printf_arglist_function1(static void lreply, int, n, char *, fmt)
+{
+    va_list args;
+    char buf[STR_SIZE];
+
+    arglist_start(args, fmt);
+    ap_snprintf(buf, sizeof(buf), "%03d-", n);
+    ap_vsnprintf(buf+4, sizeof(buf)-4, fmt, args);
+    arglist_end(args);
+
+    if (printf("%s\r\n", buf) < 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 (fflush(stdout) != 0)
+    {
+       dbprintf(("%s: ! error %d (%s) in fflush\n",
+                 debug_prefix_time(NULL), errno, strerror(errno)));
+       uncompress_remove = remove_files(uncompress_remove);
+       exit(1);
+    }
+
+    dbprintf(("%s: < %s\n", debug_prefix_time(NULL), buf));
+}
+
+/* send one line of a multi-line response */
+printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
+{
+    va_list args;
+    char buf[STR_SIZE];
+
+    arglist_start(args, fmt);
+    ap_snprintf(buf, sizeof(buf), "%03d-", n);
+    ap_vsnprintf(buf+4, sizeof(buf)-4, fmt, args);
+    arglist_end(args);
+
+    if (printf("%s\r\n", buf) < 0)
+    {
+       dbprintf(("%s: ! error %d (%s) in printf\n",
+                 debug_prefix_time(NULL), errno, strerror(errno)));
+       uncompress_remove = remove_files(uncompress_remove);
+       exit(1);
+    }
+}
+
+/* see if hostname is valid */
+/* valid is defined to be that there is an index directory for it */
+/* also do a security check on the requested dump hostname */
+/* to restrict access to index records if required */
+/* return -1 if not okay */
+int is_dump_host_valid(host)
+char *host;
+{
+    struct stat dir_stat;
+    char *fn;
+    host_t *ihost;
+
+    if (config_name == NULL) {
+       reply(501, "Must set config before setting host.");
+       return -1;
+    }
+
+#if 0
+    /* only let a client restore itself for now unless it is the server */
+    if (strcasecmp(remote_hostname, local_hostname) == 0)
+       return 0;
+    if (strcasecmp(remote_hostname, host) != 0)
+    {
+       reply(501,
+             "You don't have the necessary permissions to set dump host to %s.",
+             buf1);
+       return -1;
+    }
+#endif
+
+    /* check that the config actually handles that host */
+    ihost = lookup_host(host);
+    if(ihost == NULL) {
+       reply(501, "Host %s is not in your disklist.", host);
+       return -1;
+    }
+
+    /* assume an index dir already */
+    fn = getindexfname(host, NULL, NULL, 0);
+    if (stat (fn, &dir_stat) != 0 || !S_ISDIR(dir_stat.st_mode)) {
+       reply(501, "No index records for host: %s. Have you enabled indexing?", host);
+       amfree(fn);
+       return -1;
+    }
+
+    amfree(fn);
+    return 0;
+}
+
+
+int is_disk_valid(disk)
+char *disk;
+{
+    char *fn;
+    struct stat dir_stat;
+    disk_t *idisk;
+
+    if (config_name == NULL || dump_hostname == NULL) {
+       reply(501, "Must set config,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);
+       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);
+       amfree(fn);
+       return -1;
+    }
+
+    amfree(fn);
+    return 0;
+}
+
+
+int is_config_valid(config)
+char *config;
+{
+    char *conffile;
+    char *conf_diskfile;
+    char *conf_tapelist;
+    char *conf_indexdir;
+    struct stat dir_stat;
+
+    /* check that the config actually exists */
+    if (config == NULL) {
+       reply(501, "Must set config first.");
+       return -1;
+    }
+
+    /* read conffile */
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if (read_conffile(conffile)) {
+       reply(501, "Could not read config file %s!", conffile);
+       amfree(conffile);
+       return -1;
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if ((disk_list = read_diskfile(conf_diskfile)) == NULL) {
+       reply(501, "Could not read disk file %s!", conf_diskfile);
+       amfree(conf_diskfile);
+       return -1;
+    }
+    amfree(conf_diskfile);
+    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)) {
+       reply(501, "Could not read tapelist file %s!", conf_tapelist);
+       amfree(conf_tapelist);
+       return -1;
+    }
+    amfree(conf_tapelist);
+
+    output_find = find_dump(1, disk_list);
+    sort_find_result("DLKHB", &output_find);
+
+    /* okay, now look for the index directory */
+    conf_indexdir = getconf_str(CNF_INDEXDIR);
+    if(*conf_indexdir == '/') {
+       conf_indexdir = stralloc(conf_indexdir);
+    } else {
+       conf_indexdir = stralloc2(config_dir, conf_indexdir);
+    }
+    if (stat (conf_indexdir, &dir_stat) != 0 || !S_ISDIR(dir_stat.st_mode)) {
+       reply(501, "Index directory %s does not exist", conf_indexdir);
+       amfree(conf_indexdir);
+       return -1;
+    }
+    amfree(conf_indexdir);
+
+    return 0;
+}
+
+
+int build_disk_table P((void))
+{
+    char date[3 * NUM_STR_SIZE + 2 + 1];
+    long last_datestamp;
+    int last_filenum;
+    int last_level;
+    find_result_t *find_output;
+
+    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+       reply(590, "Must set config,host,disk before building disk table");
+       return -1;
+    }
+
+    clear_list();
+    last_datestamp = -1;
+    last_filenum = -1;
+    last_level = -1;
+    for(find_output = output_find;
+       find_output != NULL; 
+       find_output = find_output->next) {
+       if(strcasecmp(dump_hostname, find_output->hostname) == 0 &&
+          strcmp(disk_name    , find_output->diskname) == 0 &&
+          strcmp("OK"         , find_output->status)   == 0) {
+           /*
+            * The sort order puts holding disk entries first.  We want to
+            * use them if at all possible, so ignore any other entries
+            * for the same datestamp after we see a holding disk entry
+            * (as indicated by a filenum of zero).
+            */
+           if(find_output->datestamp == last_datestamp &&
+              find_output->level == last_level && last_filenum == 0) {
+               continue;
+           }
+           last_datestamp = find_output->datestamp;
+           last_filenum = find_output->filenum;
+           last_level = find_output->level;
+           ap_snprintf(date, sizeof(date), "%04d-%02d-%02d",
+                       find_output->datestamp/10000,
+                       (find_output->datestamp/100) %100,
+                       find_output->datestamp %100);
+           add_dump(date, find_output->level, find_output->label, 
+                    find_output->filenum);
+           dbprintf(("%s: - %s %d %s %d\n",
+                     debug_prefix_time(NULL), date, find_output->level, 
+                     find_output->label, find_output->filenum));
+       }
+    }
+    return 0;
+}
+
+
+int disk_history_list P((void))
+{
+    DUMP_ITEM *item;
+
+    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+       reply(502, "Must set config,host,disk before listing history");
+       return -1;
+    }
+
+    lreply(200, " Dump history for config \"%s\" host \"%s\" disk \"%s\"",
+         config_name, dump_hostname, disk_name);
+
+    for (item=first_dump(); item!=NULL; item=next_dump(item))
+       lreply(201, " %s %d %s %d", item->date, item->level, item->tape,
+              item->file);
+
+    reply(200, "Dump history for config \"%s\" host \"%s\" disk \"%s\"",
+         config_name, dump_hostname, disk_name);
+
+    return 0;
+}
+
+
+/* is the directory dir backed up - dir assumed complete relative to
+   disk mount point */
+/* opaque version of command */
+int is_dir_valid_opaque(dir)
+char *dir;
+{
+    DUMP_ITEM *item;
+    char *line = NULL;
+    FILE *fp;
+    int last_level;
+    char *ldir = NULL;
+    char *filename_gz = NULL;
+    char *filename = NULL;
+    int 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) {
+       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)
+           break;
+
+    if (item == NULL)
+    {
+       /* no dump for given date */
+       reply(500, "No dumps available on or before date \"%s\"", target_date);
+       return -1;
+    }
+
+    if(strcmp(dir, "/") == 0) {
+       ldir = stralloc(dir);
+    } else {
+       ldir = stralloc2(dir, "/");
+    }
+    ldir_len = strlen(ldir);
+
+    /* go back till we hit a level 0 dump */
+    do
+    {
+       amfree(filename);
+       filename_gz = getindexfname(dump_hostname, disk_name,
+                                   item->date, item->level);
+       if((filename = uncompress_file(filename_gz, &emsg)) == NULL) {
+           reply(599, "System error %s", emsg);
+           amfree(filename_gz);
+           amfree(emsg);
+           amfree(ldir);
+           return -1;
+       }
+       amfree(filename_gz);
+       dbprintf(("%s: f %s\n", debug_prefix_time(NULL), filename));
+       if ((fp = fopen(filename, "r")) == NULL) {
+           reply(599, "System error %s", strerror(errno));
+           amfree(filename);
+           amfree(ldir);
+           return -1;
+       }
+       for(; (line = agets(fp)) != NULL; free(line)) {
+           if (strncmp(line, ldir, ldir_len) != 0) {
+               continue;                       /* not found yet */
+           }
+           amfree(filename);
+           amfree(ldir);
+           amfree(line);
+           afclose(fp);
+           return 0;
+       }
+       afclose(fp);
+
+       last_level = item->level;
+       do
+       {
+           item=next_dump(item);
+       } while ((item != NULL) && (item->level >= last_level));
+    } while (item != NULL);
+
+    amfree(filename);
+    amfree(ldir);
+    reply(500, "\"%s\" is an invalid directory", dir);
+    return -1;
+}
+
+int opaque_ls(dir,recursive)
+char *dir;
+int  recursive;
+{
+    DUMP_ITEM *dump_item;
+    DIR_ITEM *dir_item;
+    int last_level;
+    static char *emsg = NULL;
+
+    clear_dir_list();
+
+    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+       reply(502, "Must set config,host,disk before listing a directory");
+       return -1;
+    }
+    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)
+           break;
+
+    if (dump_item == NULL)
+    {
+       /* no dump for given date */
+       reply(500, "No dumps available on or before date \"%s\"", target_date);
+       return -1;
+    }
+
+    /* get data from that dump */
+    if (process_ls_dump(dir, dump_item, recursive, &emsg) == -1) {
+       reply(599, "System error %s", emsg);
+       amfree(emsg);
+       return -1;
+    }
+
+    /* go back processing higher level dumps till we hit a level 0 dump */
+    last_level = dump_item->level;
+    while ((last_level != 0) && ((dump_item=next_dump(dump_item)) != NULL))
+    {
+       if (dump_item->level < last_level)
+       {
+           last_level = dump_item->level;
+           if (process_ls_dump(dir, dump_item, recursive, &emsg) == -1) {
+               reply(599, "System error %s", emsg);
+               amfree(emsg);
+               return -1;
+           }
+       }
+    }
+
+    /* return the information to the caller */
+    if(recursive)
+    {
+       lreply(200, " Opaque recursive list of %s", dir);
+       for (dir_item = get_dir_list(); dir_item != NULL; 
+            dir_item = dir_item->next) {
+           if(am_has_feature(their_features, fe_amindexd_fileno_in_ORLD)){
+               fast_lreply(201, " %s %d %-16s %d %s",
+                           dir_item->dump->date, dir_item->dump->level,
+                           dir_item->dump->tape, dir_item->dump->file,
+                           dir_item->path);
+           }
+           else {
+               fast_lreply(201, " %s %d %-16s %s",
+                           dir_item->dump->date, dir_item->dump->level,
+                           dir_item->dump->tape, dir_item->path);
+           }
+       }
+       reply(200, " Opaque recursive list of %s", dir);
+    }
+    else
+    {
+       lreply(200, " Opaque list of %s", dir);
+       for (dir_item = get_dir_list(); dir_item != NULL; 
+            dir_item = dir_item->next) {
+           if(am_has_feature(their_features, fe_amindexd_fileno_in_OLSD)){
+               lreply(201, " %s %d %-16s %d %s",
+                           dir_item->dump->date, dir_item->dump->level,
+                           dir_item->dump->tape, dir_item->dump->file,
+                           dir_item->path);
+           }
+           else {
+               lreply(201, " %s %d %-16s %s",
+                           dir_item->dump->date, dir_item->dump->level,
+                           dir_item->dump->tape, dir_item->path);
+           }
+       }
+       reply(200, " Opaque list of %s", dir);
+    }
+    clear_dir_list();
+    return 0;
+}
+
+
+/* returns the value of tapedev from the amanda.conf file if set,
+   otherwise reports an error */
+int tapedev_is P((void))
+{
+    char *result;
+
+    /* check state okay to do this */
+    if (config_name == NULL) {
+       reply(501, "Must set config before asking about tapedev.");
+       return -1;
+    }
+
+    /* get tapedev value */
+    if ((result = getconf_str(CNF_TAPEDEV)) == NULL)
+    {
+       reply(501, "Tapedev not set in config file.");
+       return -1;
+    }
+
+    reply(200, result);
+    return 0;
+}
+
+
+/* returns YES if dumps for disk are compressed, NO if not */
+int are_dumps_compressed P((void))
+{
+    disk_t *diskp;
+
+    /* check state okay to do this */
+    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
+       reply(501, "Must set config,host,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)
+       if ((strcasecmp(diskp->host->hostname, dump_hostname) == 0)
+           && (strcmp(diskp->name, disk_name) == 0))
+           break;
+
+    if (diskp == NULL)
+    {
+       reply(501, "Couldn't find host/disk in disk file.");
+       return -1;
+    }
+
+    /* send data to caller */
+    if (diskp->compress == COMP_NONE)
+       reply(200, "NO");
+    else
+       reply(200, "YES");
+
+    return 0;
+}
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    char *line = NULL, *part = NULL;
+    char *s, *fp;
+    int ch;
+    char *cmd_undo, cmd_undo_ch;
+    int i;
+    struct sockaddr_in his_addr;
+    struct hostent *his_name;
+    char *arg;
+    char *cmd;
+    int len;
+    int fd;
+    int user_validated = 0;
+    char *errstr = NULL;
+    char *pgm = "amindexd";                    /* in case argv[0] is not set */
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    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 (argc >= 1 && argv != NULL && argv[0] != NULL) {
+       if((pgm = strrchr(argv[0], '/')) != NULL) {
+           pgm++;
+       } else {
+           pgm = argv[0];
+       }
+    }
+
+    set_pname(pgm);
+
+#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);
+       setuid(client_uid);
+    }
+
+#endif /* FORCE_USERID */
+
+    dbopen();
+    startclock();
+    dbprintf(("%s: version %s\n", get_pname(), version()));
+
+    if (! (argc >= 1 && argv != NULL && argv[0] != NULL)) {
+       dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
+                 debug_prefix_time(NULL)));
+    }
+
+    {
+       int db_fd = dbfd();
+       if(db_fd != -1) {
+           dup2(db_fd, 2);
+       }
+    }
+
+    /* initialize */
+
+    argc--;
+    argv++;
+
+    if(argc > 0 && strcmp(*argv, "-t") == 0) {
+       amindexd_debug = 1;
+       argc--;
+       argv++;
+    }
+
+    if (argc > 0) {
+       config_name = stralloc(*argv);
+       config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+       argc--;
+       argv++;
+    }
+
+    if(gethostname(local_hostname, sizeof(local_hostname)-1) == -1)
+       error("gethostname: %s", strerror(errno));
+    local_hostname[sizeof(local_hostname)-1] = '\0';
+
+    /* now trim domain off name */
+    s = local_hostname;
+    ch = *s++;
+    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);
+       }
+       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? */
+       i = sizeof (his_addr);
+       if (getpeername(0, (struct sockaddr *)&his_addr, &i) == -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_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));
+    }
+    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(disk_name);
+    amfree(target_date);
+
+    our_features = am_init_feature_set();
+    their_features = am_set_default_feature_set();
+
+    if (config_name != NULL && is_config_valid(config_name) != -1) {
+       return 1;
+    }
+
+    reply(220, "%s AMANDA index server (%s) ready.", local_hostname,
+         version());
+
+    /* 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) {
+                   dbprintf(("%s: ? read error: %s\n",
+                             debug_prefix_time(NULL), strerror(errno)));
+               } else {
+                   dbprintf(("%s: ? unexpected EOF\n",
+                             debug_prefix_time(NULL)));
+               }
+               if(line) {
+                   dbprintf(("%s: ? unprocessed input:\n",
+                             debug_prefix_time(NULL)));
+                   dbprintf(("-----\n"));
+                   dbprintf(("%s\n", line));
+                   dbprintf(("-----\n"));
+               }
+               amfree(line);
+               amfree(part);
+               uncompress_remove = remove_files(uncompress_remove);
+               dbclose();
+               return 1;               /* they hung up? */
+           }
+           if(line) {
+               strappend(line, part);
+               amfree(part);
+           } else {
+               line = part;
+               part = NULL;
+           }
+           if(amindexd_debug) {
+               break;                  /* we have a whole line */
+           }
+           if((len = strlen(line)) > 0 && line[len-1] == '\r') {
+               line[len-1] = '\0';     /* zap the '\r' */
+               break;
+           }
+           /*
+            * Hmmm.  We got a "line" from agets(), 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");
+       }
+
+       dbprintf(("%s: > %s\n", debug_prefix_time(NULL), line));
+
+       arg = NULL;
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           reply(500, "Command not recognised/incorrect: %s", line);
+           continue;
+       }
+       cmd = s - 1;
+
+       skip_non_whitespace(s, ch);
+       cmd_undo = s-1;                         /* for error message */
+       cmd_undo_ch = *cmd_undo;
+       *cmd_undo = '\0';
+       if (ch) {
+           skip_whitespace(s, ch);             /* find the argument */
+           if (ch) {
+               arg = s-1;
+               skip_non_whitespace(s, ch);
+           }
+       }
+
+       amfree(errstr);
+       if (!user_validated && strcmp(cmd, "SECURITY") == 0 && arg) {
+           user_validated = security_ok(&his_addr, arg, 0, &errstr);
+           if(user_validated) {
+               reply(200, "Access OK");
+               continue;
+           }
+       }
+       if (!user_validated) {
+           if (errstr) {
+               reply(500, "Access not allowed: %s", errstr);
+           } else {
+               reply(500, "Access not allowed");
+           }
+           break;
+       }
+
+       if (strcmp(cmd, "QUIT") == 0) {
+           break;
+       } else if (strcmp(cmd, "HOST") == 0 && arg) {
+           /* set host we are restoring */
+           s[-1] = '\0';
+           if (is_dump_host_valid(arg) != -1)
+           {
+               dump_hostname = newstralloc(dump_hostname, arg);
+               reply(200, "Dump host set to %s.", dump_hostname);
+               amfree(disk_name);              /* invalidate any value */
+           }
+           s[-1] = ch;
+       } else if (strcmp(cmd, "DISK") == 0 && arg) {
+           s[-1] = '\0';
+           if (is_disk_valid(arg) != -1) {
+               disk_name = newstralloc(disk_name, arg);
+               if (build_disk_table() != -1) {
+                   reply(200, "Disk set to %s.", disk_name);
+               }
+           }
+           s[-1] = ch;
+       } else if (strcmp(cmd, "LISTDISK") == 0) {
+           disk_t *disk;
+           int nbdisk = 0;
+           s[-1] = '\0';
+           if (config_name == NULL || dump_hostname == NULL) {
+               reply(501, "Must set config, 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);
+                       nbdisk++;
+                   }
+               }
+               if(nbdisk > 0) {
+                   reply(200, "List of disk for device %s on host %s", arg,
+                         dump_hostname);
+               }
+               else {
+                   reply(200, "No disk for device %s on host %s", arg,
+                         dump_hostname);
+               }
+           }
+           else {
+               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);
+                       nbdisk++;
+                   }
+               }
+               if(nbdisk > 0) {
+                   reply(200, "List of disk for host %s", dump_hostname);
+               }
+               else {
+                   reply(200, "No disk for host %s", dump_hostname);
+               }
+           }
+           s[-1] = ch;
+       } else if (strcmp(cmd, "SCNF") == 0 && arg) {
+           s[-1] = '\0';
+           amfree(config_name);
+           amfree(config_dir);
+           config_name = newstralloc(config_name, arg);
+           config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+           if (is_config_valid(arg) != -1) {
+               amfree(dump_hostname);          /* 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;
+       } else if (strcmp(cmd, "FEATURES") == 0 && arg) {
+           char *our_feature_string = NULL;
+           char *their_feature_string = NULL;
+           s[-1] = '\0';
+           am_release_feature_set(our_features);
+           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_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;
+       } 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;
+       } else if (strcmp(cmd, "DHST") == 0) {
+           (void)disk_history_list();
+       } else if (strcmp(cmd, "OISD") == 0 && arg) {
+           if (is_dir_valid_opaque(arg) != -1) {
+               reply(200, "\"%s\" is a valid directory", arg);
+           }
+       } else if (strcmp(cmd, "OLSD") == 0 && arg) {
+           (void)opaque_ls(arg,0);
+       } else if (strcmp(cmd, "ORLD") == 0 && arg) {
+           (void)opaque_ls(arg,1);
+       } else if (strcmp(cmd, "TAPE") == 0) {
+           (void)tapedev_is();
+       } else if (strcmp(cmd, "DCMP") == 0) {
+           (void)are_dumps_compressed();
+       } else {
+           *cmd_undo = cmd_undo_ch;    /* restore the command line */
+           reply(500, "Command not recognised/incorrect: %s", cmd);
+       }
+    }
+    amfree(line);
+
+    uncompress_remove = remove_files(uncompress_remove);
+    free_find_result(&output_find);
+    reply(200, "Good bye.");
+    dbclose();
+    return 0;
+}
diff --git a/server-src/amlabel.c b/server-src/amlabel.c
new file mode 100644 (file)
index 0000000..4e0ae46
--- /dev/null
@@ -0,0 +1,441 @@
+/*
+ * 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: amlabel.c,v 1.18.2.15.4.3.2.4 2003/01/01 23:28:53 martinea Exp $
+ *
+ * write an Amanda label on a tape
+ */
+#include "amanda.h"
+#include "conffile.h"
+#include "tapefile.h"
+#include "tapeio.h"
+#include "changer.h"
+
+#ifdef HAVE_LIBVTBLC
+#include <vtblc.h>
+#endif /* HAVE_LIBVTBLC */
+
+/* local functions */
+
+void usage P((char *argv0));
+
+void usage(argv0)
+char *argv0;
+{
+    fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>]\n",
+           argv0);
+    exit(1);
+}
+
+int main(argc, argv)
+    int argc;
+    char **argv;
+{
+    char *conffile;
+    char *conf_tapelist;
+    char *outslot = NULL;
+    char *errstr = NULL, *label, *oldlabel=NULL, *tapename = NULL;
+    char *labelstr, *slotstr;
+    char *olddatestamp=NULL;
+    char *conf_tapelist_old;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    int fd;
+    int have_changer;
+    int force, tape_ok;
+    tape_t *tp;
+    tapetype_t *tape;
+    long tt_blocksize_kb;
+    int slotcommand;
+    uid_t uid_me;
+    uid_t uid_dumpuser;
+    char *dumpuser;
+    struct passwd *pw;
+
+#ifdef HAVE_LIBVTBLC
+    int vtbl_no      = -1;
+    char *datestr    = NULL;
+    char *rawtapedev = NULL;
+    int first_seg, last_seg;
+#endif /* HAVE_LIBVTBLC */
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amlabel");
+    dbopen();
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = ERR_INTERACTIVE;
+
+    if(argc > 1 && strcmp(argv[1],"-f") == 0)
+        force=1;
+    else force=0;
+
+    if(argc != 3+force && argc != 5+force)
+       usage(argv[0]);
+
+    config_name = argv[1+force];
+    label = argv[2+force];
+
+    if(argc == 5+force) {
+       if(strcmp(argv[3+force], "slot"))
+           usage(argv[0]);
+       slotstr = argv[4+force];
+       slotcommand = 1;
+    } else {
+       slotstr = "current";
+       slotcommand = 0;
+    }
+
+    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);
+    }
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+
+    uid_me = getuid();
+    uid_dumpuser = uid_me;
+    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);
+       /* NOTREACHED */
+    }
+
+    labelstr = getconf_str(CNF_LABELSTR);
+
+    if(!match(labelstr, label))
+       error("label %s doesn't match labelstr \"%s\"", label, labelstr);
+
+    if((tp = lookup_tapelabel(label))!=NULL) {
+       if(!force)
+           error("label %s already on a tape\n",label);
+    }
+    tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
+    tt_blocksize_kb = tape->blocksize;
+
+    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]);
+       }
+       tapename = stralloc(getconf_str(CNF_TAPEDEV));
+#ifdef HAVE_LIBVTBLC
+       rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
+#endif /* HAVE_LIBVTBLC */
+    } else if(have_changer != 1) {
+       error("changer initialization failed: %s", strerror(errno));
+    } else {
+       if(changer_loadslot(slotstr, &outslot, &tapename)) {
+           error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
+       }
+
+       printf("labeling tape in slot %s (%s):\n", outslot, tapename);
+    }
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+    if (is_zftape(tapename) == 1){
+       if((fd = tape_open(tapename, O_WRONLY)) == -1) {
+           errstr = newstralloc2(errstr, "amlabel: ",
+                                 (errno == EACCES) ? "tape is write-protected"
+                                 : strerror(errno));
+           error(errstr);
+       }
+    }
+#endif /* HAVE_LINUX_ZFTAPE_H */
+
+    printf("rewinding"); fflush(stdout);
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+    if (is_zftape(tapename) == 1){
+       if(tapefd_rewind(fd) == -1) {
+           putchar('\n');
+           error(strerror(errno));
+       }
+    }
+    else
+#endif /* HAVE_LINUX_ZFTAPE_H */
+    if((errstr = tape_rewind(tapename)) != NULL) {
+       putchar('\n');
+       error(errstr);
+    }
+
+    tape_ok=1;
+    printf(", reading label");fflush(stdout);
+    if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
+       printf(", %s\n",errstr);
+       tape_ok=1;
+    }
+    else {
+       /* got an amanda tape */
+       printf(" %s",oldlabel);
+       if(strcmp(oldlabel, FAKE_LABEL) != 0
+          && match(labelstr, oldlabel) == 0) {
+           printf(", tape is in another amanda configuration");
+           if(!force)
+               tape_ok=0;
+       }
+       else {
+           if((tp = lookup_tapelabel(oldlabel)) != NULL) {
+               printf(", tape is active");
+               if(!force)
+                   tape_ok=0;
+           }
+       }
+       printf("\n");
+    }
+    amfree(oldlabel);
+    amfree(olddatestamp);
+       
+    printf("rewinding"); fflush(stdout);
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+    if (is_zftape(tapename) == 1){
+       if(tapefd_rewind(fd) == -1) {
+           putchar('\n');
+           error(strerror(errno));
+       }
+    }
+    else
+#endif /* HAVE_LINUX_ZFTAPE_H */
+    if((errstr = tape_rewind(tapename)) != NULL) {
+       putchar('\n');
+       error(errstr);
+    }
+
+    if(tape_ok) {
+       printf(", writing label %s", label); fflush(stdout);
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+       if (is_zftape(tapename) == 1){
+           errstr = tapefd_wrlabel(fd, "X", label, tt_blocksize_kb * 1024);
+           if(errstr != NULL) {
+               putchar('\n');
+               error(errstr);
+           }
+       }
+       else
+#endif /* HAVE_LINUX_ZFTAPE_H */
+       errstr = tape_wrlabel(tapename, "X", label, tt_blocksize_kb * 1024);
+       if(errstr != NULL) {
+           putchar('\n');
+           error(errstr);
+       }
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+       if (is_zftape(tapename) == 1){
+           tapefd_weof(fd, 1);
+       }
+#endif /* HAVE_LINUX_ZFTAPE_H */
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+       if (is_zftape(tapename) == 1){
+           errstr = tapefd_wrendmark(fd, "X", tt_blocksize_kb * 1024);
+           if(errstr != NULL) {
+               putchar('\n');
+               error(errstr);
+           }
+       }
+       else
+#endif /* HAVE_LINUX_ZFTAPE_H */
+       errstr = tape_wrendmark(tapename, "X", tt_blocksize_kb * 1024);
+       if(errstr != NULL) {
+           putchar('\n');
+           error(errstr);
+       }
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+       if (is_zftape(tapename) == 1){
+           tapefd_weof(fd, 1);
+
+           printf(",\nrewinding"); fflush(stdout); 
+     
+           if(tapefd_rewind(fd) == -1) { 
+               putchar('\n'); 
+               error(strerror(errno)); 
+           } 
+           close(fd);
+#ifdef HAVE_LIBVTBLC
+           /* update volume table */
+           printf(", updating volume table"); fflush(stdout);
+    
+           if ((fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
+               if(errno == EACCES) {
+                   errstr = newstralloc(errstr,
+                                        "updating volume table: raw tape device is write protected");
+               } else {
+                   errstr = newstralloc2(errstr,
+                                         "updating volume table: ", strerror(errno));
+               }
+               putchar('\n');
+               error(errstr);
+           }
+           /* read volume table */
+           if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
+                                        &first_seg, &last_seg)) == -1 ) {
+               errstr = newstralloc2(errstr,
+                                     "reading volume table: ", strerror(errno));
+               putchar('\n');
+               error(errstr);
+           }
+           /* set date and volume label for first entry */
+           vtbl_no = 0;
+           datestr = NULL; 
+           if (set_date(datestr, volumes, num_volumes, vtbl_no)){
+               errstr = newstralloc2(errstr,
+                                     "setting date for entry 1: ", strerror(errno));
+               putchar('\n');
+               error(errstr);
+           }
+           if(set_label(label, volumes, num_volumes, vtbl_no)){
+               errstr = newstralloc2(errstr,
+                                     "setting label for entry 1: ", strerror(errno));
+               putchar('\n');
+               error(errstr);
+           }
+           /* set date and volume label for last entry */
+           vtbl_no = 1;
+           datestr = NULL; 
+           if (set_date(datestr, volumes, num_volumes, vtbl_no)){
+               errstr = newstralloc2(errstr,
+                                     "setting date for entry 2: ", strerror(errno));
+               putchar('\n');
+               error(errstr);
+           }
+           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);
+           }
+           /* write volume table back */
+           if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
+                          op_mode == trunc)) {
+               errstr = newstralloc2(errstr,
+                                     "writing volume table: ", strerror(errno));
+               putchar('\n');
+               error(errstr);
+           }  
+           close(fd);
+#endif /* HAVE_LIBVTBLC */
+       }
+#endif /* HAVE_LINUX_ZFTAPE_H */
+
+       if (tape_ok) {
+           printf(", checking label"); fflush(stdout);
+
+           if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
+               putchar('\n');
+               if (strcmp(errstr, "not an amanda tape") != 0)
+                   error(errstr);
+               error("no label found, are you sure %s is non-rewinding?",
+                     tapename);
+           }
+
+           if (strcmp("X", olddatestamp) != 0 ||
+               (strcmp(oldlabel, FAKE_LABEL) != 0
+                && strcmp(label, oldlabel) != 0)) {
+               putchar('\n');
+               error("read label %s back, timestamp %s (expected X), what now?",
+                     oldlabel, olddatestamp);
+           }
+           amfree(oldlabel);
+           amfree(olddatestamp);
+
+           /* write tape list */
+
+           /* make a copy */
+                   conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
+           if(write_tapelist(conf_tapelist_old)) {
+               error("couldn't write tapelist: %s", strerror(errno));
+           }
+           amfree(conf_tapelist_old);
+
+           /* XXX add cur_tape number to tape list structure */
+           remove_tapelabel(label);
+           add_tapelabel(0, label);
+           if(write_tapelist(conf_tapelist)) {
+               error("couldn't write tapelist: %s", strerror(errno));
+           }
+       } /* 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");
+    }
+
+    amfree(outslot);
+    amfree(tapename);
+    amfree(conffile);
+    amfree(conf_tapelist);
+    amfree(config_dir);
+    config_name=NULL;
+
+    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);
+    }
+
+    dbclose();
+    return 0;
+}
diff --git a/server-src/amlogroll.c b/server-src/amlogroll.c
new file mode 100644 (file)
index 0000000..728ee3a
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: amlogroll.c,v 1.1.2.1.4.1.2.3 2003/10/27 17:55:39 martinea Exp $
+ *
+ * rename a live log file to the datestamped name.
+ */
+
+#include "amanda.h"
+#include "conffile.h"
+#include "logfile.h"
+#include "version.h"
+
+char *datestamp;
+
+void handle_start P((void));
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    char *conffile;
+    char *logfname;
+    char *conf_logdir;
+    FILE *logfile;
+    int fd;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    char my_cwd[STR_SIZE];
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("amlogroll");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    /* Process options */
+    
+    erroutput_type = ERR_INTERACTIVE;
+
+    if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       error("cannot determine current working directory");
+    }
+
+    if (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_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+    }
+
+    safe_cd();
+
+    /* read configuration files */
+
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if(read_conffile(conffile)) {
+        error("errors processing config file \"%s\"", conffile);
+    }
+    amfree(conffile);
+
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+        conf_logdir = stralloc(conf_logdir);
+    } else {
+        conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    logfname = vstralloc(conf_logdir, "/", "log", NULL);
+    amfree(conf_logdir);
+
+    if((logfile = fopen(logfname, "r")) == NULL) {
+       error("could not open log %s: %s", logfname, strerror(errno));
+    }
+    amfree(logfname);
+
+    erroutput_type |= ERR_AMANDALOG;
+    set_logerror(logerror);
+
+    while(get_logline(logfile)) {
+       if(curlog == L_START) {
+           handle_start();
+           if(datestamp != NULL) {
+               break;
+           }
+       }
+    }
+    afclose(logfile);
+    log_rename(datestamp);
+
+    amfree(datestamp);
+    amfree(config_dir);
+    amfree(config_name);
+
+    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 0;
+}
+
+void handle_start()
+{
+    static int started = 0;
+    char *s, *fp;
+    int ch;
+
+    if(!started) {
+       s = curstr;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+#define sc "date"
+       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           return;                             /* ignore bogus line */
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           return;
+       }
+       fp = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       datestamp = newstralloc(datestamp, fp);
+       s[-1] = ch;
+
+       started = 1;
+    }
+}
diff --git a/server-src/amoverview.pl.in b/server-src/amoverview.pl.in
new file mode 100644 (file)
index 0000000..15a943d
--- /dev/null
@@ -0,0 +1,170 @@
+#!@PERL@
+
+# Catch for sh/csh on systems without #! ability.
+eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
+       & eval 'exec @PERL@ -S $0 $argv:q'
+               if 0;
+
+require 5.001;
+
+use FileHandle;
+use Getopt::Long;
+use Carp;
+use POSIX;
+
+sub Usage {
+    print STDERR <<END;
+Usage: $0 [[-config] CONFIG] [-hostwidth width] [-diskwidth width] [-verbose]
+
+This script generates to standard output an overview of the filesystems
+dumped over time and the type of dump done on a particular day, such as
+a full dump, or an incremental, or if the dump failed.
+
+You may override the default configuration `@DEFAULT_CONFIG@' by using
+the -config command line option.  On larger installations, this script
+will take a while to run.  In this case, run it with --verbose to see
+how far along it is.
+END
+    exit 1;
+}
+
+# Default paths for this installation of Amanda.
+my $prefix='@prefix@';
+$prefix=$prefix;               # avoid warnings about possible typo
+my $exec_prefix="@exec_prefix@";
+$exec_prefix=$exec_prefix;     # ditto
+my $libexecdir="@libexecdir@";
+my $sbindir="@sbindir@";
+# The directory where configurations can be found.
+my $confdir="@CONFIG_DIR@";
+
+# The default configuration.
+my $config="@DEFAULT_CONFIG@";
+
+# Get the version suffix.
+my $USE_VERSION_SUFFIXES = '@USE_VERSION_SUFFIXES@';
+my $suf = '';
+if ( $USE_VERSION_SUFFIXES =~ /^yes$/i ) {
+       $suf='-@VERSION@';
+}
+
+my $amadmin    = "$sbindir/amadmin$suf";
+
+# overrideable defaults
+my $opt_config         = "$config";
+my $opt_hostwidth      = 8;
+my $opt_diskwidth      = 20;
+my $opt_verbose                = 0;
+
+GetOptions('config=s'          => \$opt_config,
+          'hostwidth=i'        => \$opt_hostwidth,
+          'diskwidth=i'        => \$opt_diskwidth,
+          'verbose'            => \$opt_verbose)
+or Usage();
+
+if($#ARGV == 0) {
+  $opt_config = $ARGV[0];
+}
+elsif($#ARGV > 0) {
+  Usage();
+}
+
+-d "$confdir/$opt_config" or
+       die "$0: directory `$confdir/$opt_config' does not exist.\n";
+
+# read disklist
+my %disks = ();
+$::host = '';
+$::disk = '';
+$opt_verbose and
+    print STDERR "Running $amadmin $opt_config disklist\n";
+my $dlfh = new FileHandle "$amadmin $opt_config disklist|" or
+    die "$0: error in opening `$amadmin $opt_config disklist' pipe: $!\n";
+$/ = "";
+while (<$dlfh>) {
+    ($host, $disk) = m/    host (.*?):.*    disk (.*?):/s;
+    next unless $host;
+    $disks{$host}{$disk}++;
+}
+
+$/ = "\n";
+$dlfh->close or
+    die "$0: error in closing `$amadmin $opt_config disklist|' pipe: $!\n";
+
+# Get backup dates
+%::dates = ();
+%::level = ();
+$::level = '';
+my ($date, $tape, $file, $status);
+$opt_verbose and
+    print STDERR "Running $amadmin $opt_config find\n";
+my $fh = new FileHandle "$amadmin $opt_config find|" or
+    die "$0: error in opening `$amadmin $opt_config find' pipe: $!\n";
+<$fh>;
+while (<$fh>) {
+    chomp;
+    next if /found Amanda directory/;
+    next if /skipping cruft directory/;
+    ($date, $host, $disk, $level, $tape, $file, $status) = split ' ', $_;
+    next if $date eq 'date';
+    next if $date eq 'Warning:';
+    next if $date eq 'Scanning';
+    next if $date eq "";
+    if ($date =~ /^\d\d\d\d-\d\d-\d\d$/) {
+       defined($level{$host}{$disk}{$date}) or
+           $level{$host}{$disk}{$date} = '';
+       $level{$host}{$disk}{$date} .= ($status eq 'OK') ? $level : 'E';
+       $dates{$date}++;
+    }
+    else {
+       print "bad date $date in $_\n";
+    }
+}
+$fh->close or
+    die "$0: error in closing `$amadmin $opt_config find|' pipe: $!\n";
+
+# touch all the dates just in case whole days were missed.
+{
+    my ($start, $finish) = 
+       map {
+           my($y,$m,$d) = split /-/, $_;
+           POSIX::mktime(0,0,0,$d,$m-1,$y-1900);
+       } (sort keys %dates)[0,-1];
+
+    while ($start < $finish) {
+       my @l = localtime $start;
+       $dates{sprintf("%d-%02d-%02d", 1900+$l[5], $l[4]+1, $l[3])}++;
+       $start += 86400;
+    }
+}
+    
+
+# make formats
+
+my $top_format = "format TOP =\n\n" .
+    sprintf("%-0${opt_hostwidth}s %-0${opt_diskwidth}s ", '', 'date') .
+    join(' ', map((split(/-/, $_))[1], sort keys %dates)) . "\n" .
+    sprintf("%-0${opt_hostwidth}s %-0${opt_diskwidth}s ", 'host', 'disk') .
+    join(' ', map((split(/-/, $_))[2], sort keys %dates)) . "\n" .
+    "\n.\n";
+
+my $out_format = "format STDOUT =\n" .
+    "@" . "<" x ($opt_hostwidth - 1) . ' ' .
+    "@" . "<" x ($opt_diskwidth - 1) . ' ' .
+    '@> ' x scalar(keys %dates) . "\n" .
+    join(', ', '$host', '$disk', 
+        map("substr(\$level{\$host}{\$disk}{'$_'},-2)", sort keys %dates)) . "\n" .
+    ".\n";
+
+eval $top_format;
+die $@ if $@;
+$^ = 'TOP';
+eval $out_format;
+die $@ if $@;
+
+for $host (sort keys %disks) {
+    for $disk (sort keys %{$disks{$host}}) {
+       write;
+    }
+}
diff --git a/server-src/amrmtape.sh.in b/server-src/amrmtape.sh.in
new file mode 100644 (file)
index 0000000..2138262
--- /dev/null
@@ -0,0 +1,267 @@
+#!/bin/sh
+#
+# amrmtape.sh
+# Time-stamp: <96/10/23 12:07:21 adrian>
+# Copyright 1996, Adrian Filipi-Martin
+#
+# amrmtape
+#
+# Summary:  This script allow you to invalidate the contents of an
+# existing backup tape within the Amanda current tape database.  This
+# is meant as a recovery mecanism for when a good backup is damaged
+# either by faulty hardware or user error, i.e. the tape is eaten by
+# the tape drive, or the tape has been overwritten.
+#
+# To remove a tape you must specify the Amanda configuration to
+# operate upon as well as the name of the tape. e.g.
+#
+# amrmtape nvl NVL-006
+#
+# N.B.  amrmtape must be run as a user that can read the tape database
+# files and rewrite them.
+#
+# Usage: amrmtape [-n] [-v] [-q] [-d] <configuration> <label>
+#          -n Do nothing to original files, leave new ones in --with-tmpdir
+#            directory.
+#          -v Verbose mode.  Enabled by default.
+#          -q Quiet (opposite of -v).
+#          -d Enable debug tracing.
+#
+# Credits: The what-to-do algorithm was provided by Cedric Scott,
+#          cedric.scott@sse.ie. 
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+ConfigDir=@CONFIG_DIR@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if test "$USE_VERSION_SUFFIXES" = "yes"; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+Program=`basename $0`
+
+CleanTapelist () {
+  [ "xyes" = "x${DebugMode}" ] && set -x
+
+  #
+  # Check if the configuration directory exists.  Make sure that the
+  # necessary files can be found, such as amanda.conf and tapelist.
+  #
+  if [ ! -d ${ConfigDir}/${Config} ]; then
+    log "${Program}: configuration directory ${ConfigDir}/${Config} does not exist."
+    return 1
+  fi
+  (cd ${ConfigDir}/${Config} >/dev/null 2>&1) || return $?
+  cd ${ConfigDir}/${Config}
+  if [ ! -r amanda.conf ]; then
+    log "${Program}: amanda.conf not found or is not readable in ${ConfigDir}."
+    return 1
+  fi
+
+  dumpuser=`amgetconf$SUF dumpuser`
+  runuser=`whoami`
+  if [ $runuser != $dumpuser ]; then
+    log "${Program}: must be run as user $dumpuser"
+    return 1
+  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`
+  if [ ! "$TapeList" ]; then
+    TapeList="$ConfigDir/$Config/tapelist"
+  fi
+  if [ ! -r $TapeList ]; then
+    log "${Program}: $TapeList not found or is not readable."
+    return 1
+  fi
+
+  # Get the location and name of the database filename.
+  InfoFile=`amgetconf${SUF} infofile`
+  if [ ! "$InfoFile" ]; then
+    log "${Program}: unable to find name of infofile from ${ConfigDir}/${Config}/amanda.conf."
+    return 1
+  fi
+  VarDir=`echo "$InfoFile" | sed -e 's%^[^/]*$%.%' -e 's%/[^/]*$%%'`
+
+  # Check that the database directory and files really exist.
+  if [ ! -d "${VarDir}" ]; then
+    log "${Program}: ${VarDir} does not exist or is not a directory."
+    return 1
+  fi
+  for dbext in @DB_EXT@; do
+    if [ ! -r ${InfoFile}${dbext} ] && [ ! -d ${InfoFile}${dbext} ]; then
+      log "${Program}: ${InfoFile}${dbext} does not exist or is not readable."
+      return 1
+    fi
+  done
+
+  if [ ! -d @AMANDA_TMPDIR@ ]; then
+    log "${Program}: directory @AMANDA_TMPDIR@ does not exist."
+    exit 1
+  fi
+
+  NewTapelist=@AMANDA_TMPDIR@/tapelist
+  rm -f ${NewTapelist}
+  awk "\$2 == \"${Tape}\" { next; } { print; }" \
+      > ${NewTapelist} < $TapeList ||
+  return $?
+  if [ "xno" = "x${DoNothing}" ]; then
+    lines=`wc -l < $TapeList`
+    linesafter=`wc -l < $NewTapelist`
+    if [ "$lines" -gt "$linesafter" ]; then
+      cp -p $TapeList ${TapeList}~ && (
+        if test "$lines" -gt 1; then
+          [ -s ${NewTapelist} ] &&
+            cp ${NewTapelist} $TapeList &&
+            rm -f ${NewTapelist}
+        else
+          [ -f ${NewTapelist} ] &&
+            cp ${NewTapelist} $TapeList &&
+            rm -f ${NewTapelist}
+        fi
+      )
+      log "${Program}: remove label ${Tape}."
+    else
+      log "${Program}: no such tape: ${Tape}."
+      return 1
+    fi
+  fi
+  
+  return $?
+}
+
+
+CleanCurinfo () {
+  [ "xyes" = "x${DebugMode}" ] && set -x
+  (cd ${VarDir} >/dev/null 2>&1) || return $?
+  cd ${VarDir}
+  InfoFileBase=`echo $InfoFile | sed -e 's%.*/%%g'`
+
+  TmpSrc=$InfoFileBase.orig.$$
+  TmpDest=$InfoFileBase.new.$$
+  rm -f ${TmpSrc} ${TmpDest}
+  amadmin${SUF} ${Config} export > ${TmpSrc} || return $?
+  log "${Program}: preserving original database in ${TmpSrc} (exported)."
+  exec < ${TmpSrc} > ${TmpDest} || return $?
+  DeadLevel=10
+  while read Line; do
+    case ${Line} in
+      CURINFO*|"#"*|command*|last_level*|consecutive_runs*|full*|incr*)
+       echo "${Line}"
+        ;;
+      host*)
+       set ${Line}
+        Host=$2
+       echo "${Line}"
+        ;;
+      disk*)
+       set ${Line}
+        Disk=$2
+       echo "${Line}"
+        ;;
+      stats*)
+       set ${Line}
+       if [ $# -lt 6 ] || [ $# -gt 8 ]; then
+         log "${Program}: unexpected number of fields in 'stats' entry for ${Host}:${Disk}."
+         log "${Line}"
+         return 1
+       fi
+       Level=$2
+       CurrentTape=$8
+       if [ "${CurrentTape}" = "${Tape}" ]; then
+         DeadLevel=${Level}
+         ${Verbose} "Discarding Host: ${Host}, Disk: ${Disk}, Level: ${Level}"
+       elif [ $Level -gt $DeadLevel ]; then
+         ${Verbose} "Discarding Host: ${Host}, Disk: ${Disk}, Level: ${Level}"
+       else
+         echo "${Line}"
+       fi
+       ;;
+      //)
+       echo "${Line}"
+       DeadLevel=10
+       ;;
+      *)
+       log "Error: unrecognized line of input: \"${Line}\""
+       return 1
+    esac
+  done
+  exec < /dev/tty > /dev/tty
+
+  if [ "xno" = "x${DoNothing}" ]; then
+    [ -s ${TmpDest} ] && 
+    amadmin${SUF} ${Config} import < ${TmpDest} &&
+    rm -f ${TmpDest}
+  fi
+
+  return $?
+}
+
+
+log () {
+  echo 1>&2 "$@"
+  return 0
+}
+
+
+usage () {
+  echo "${Program} [-n] [-v] [-q] [-d] <configuration> <label>"
+  echo "  -n Do nothing to original files, leave new ones in database directory."
+  echo "  -v Verbose, list backups of hosts and disks that are being discarded."
+  echo "  -q Quiet, opposite of -v."
+  echo "  -d Enable debug tracing."  
+  echo "This program allows you to invalidate the contents of an existing"
+  echo "backup tape within the Amanda current tape database.  This is meant as"
+  echo "a recovery mecanism for when a good backup is damaged either by faulty"
+  echo "hardware or user error, i.e. the tape is eaten by the tape drive, or"
+  echo "the tape has been overwritten."
+  return 0
+}
+
+
+Verbose="log "
+DoNothing="no"
+DebugMode="no"
+
+set dummy ${1+"$@"}
+while shift 2>/dev/null; do
+  case "$1" in
+    -q)
+      Verbose=": "
+      ;;
+    -v)
+      Verbose="log "
+      ;;
+    -n)
+      DoNothing="yes"
+      ;;
+    -d)
+      DebugMode="yes"
+      ;;
+    *)
+      if [ $# = 2 ]; then
+        Config=$1
+        Tape=$2
+       break
+      else
+        usage 1>&2
+       exit 1
+      fi
+
+  esac
+done
+
+( CleanTapelist && CleanCurinfo )
+exit $?
diff --git a/server-src/amstatus.pl.in b/server-src/amstatus.pl.in
new file mode 100644 (file)
index 0000000..d548960
--- /dev/null
@@ -0,0 +1,1193 @@
+#!@PERL@ -w
+#
+
+# Run perl.
+eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
+        & eval 'exec @PERL@ -S $0 $argv:q'
+               if 0;
+
+require "newgetopt.pl";
+use Time::Local;
+
+$confdir="@CONFIG_DIR@";
+$prefix='@prefix@';
+$prefix=$prefix;               # avoid warnings about possible typo
+$exec_prefix="@exec_prefix@";
+$exec_prefix=$exec_prefix;     # ditto
+$sbindir="@sbindir@";
+
+$USE_VERSION_SUFFIXES='@USE_VERSION_SUFFIXES@';
+$suf = '';
+if ( $USE_VERSION_SUFFIXES =~ /^yes$/i ) {
+        $suf='-@VERSION@';
+}
+
+$result = &NGetOpt (   "summary",
+                       "stats|statistics",
+                       "dumping|d",
+                       "waitdumping|wdumping",
+                       "waittaper|wtaper",
+                       "dumpingtape|dtape",
+                       "writingtape|wtape",
+                       "finished",
+                       "failed|error",
+                       "estimate",
+                       "gestimate|gettingestimate",
+                       "date",
+                       "config|c:s",
+                       "file:s",
+                       );
+if($result !=1 ) {
+       &usage();
+}
+
+if( defined $opt_config ) {
+       $conf = $opt_config;
+}
+else {
+       if($#ARGV == 0 ) {
+               $conf=$ARGV[0];
+       }
+       else {
+               &usage();
+       }
+}
+
+if ( ! -d "$confdir/$conf" ) {
+    die "amstatus$suf: could not find directory $confdir/$conf";
+}
+
+$pwd = `pwd`;
+chomp $pwd;
+chdir "$confdir/$conf";
+
+$logdir=`$sbindir/amgetconf$suf logdir`;
+exit 1 if $? != 0;
+chomp $logdir;
+$errfile="$logdir/amdump";
+
+$nb_options = defined( $opt_summary ) +
+                                 defined( $opt_stats ) +
+                                 defined( $opt_dumping ) +
+                                 defined( $opt_waitdumping ) +
+                                 defined( $opt_waittaper ) +
+                                 defined( $opt_dumpingtape ) +
+                                 defined( $opt_writingtape ) +
+                                 defined( $opt_finished ) +
+                                 defined( $opt_estimate ) +
+                                 defined( $opt_gestimate ) +
+                                 defined( $opt_failed );
+
+if($nb_options == 0 ) {
+       $opt_summary     = 1;
+       $opt_stats       = 1; 
+       $opt_dumping     = 1;
+       $opt_waitdumping = 1;
+       $opt_waittaper   = 1;
+       $opt_dumpingtape = 1;
+       $opt_writingtape = 1;
+       $opt_finished    = 1;
+       $opt_failed      = 1;
+       $opt_gestimate   = 1;
+       $opt_estimate    = 1;
+}
+
+if( defined $opt_file) {
+       if( $opt_file =~ m,^/, ) {
+               $errfile = $opt_file;
+       } else {
+               $errfile = "$pwd/$opt_file";
+               $errfile = "$logdir/$opt_file" if ( ! (-f $errfile ));
+       }
+}
+else {
+       $errfile="$logdir/amflush" if(! (-f $errfile));
+       if (! -f $errfile) {
+               if (-f "$logdir/amflush.1" && -f "$logdir/amdump.1" &&
+                   -M "$logdir/amflush.1"  < -M "$logdir/amdump.1") {
+                       $errfile="$logdir/amflush.1";
+               } else {
+                       $errfile="$logdir/amdump.1";
+               }
+       }
+}
+
+open(AMDUMP,"<$errfile") || die("$errfile: $!");
+print "Using $errfile";
+
+$start_degraded_mode = 0;
+
+$label = "";                                   # -w fodder
+$origsize = 0;                                 # -w fodder
+$idle_dumpers = 0;
+$status_driver = "";
+$status_taper = 0;
+$estimate_done = 0;
+$holding_space = 0;
+$start_time = 0;
+@dumpers_active = ();
+$nb_tape = 0;
+$ntpartition{$nb_tape} = 0;
+$ntsize{$nb_tape} = 0;
+$ntesize{$nb_tape} = 0;
+$tape_size = 0;
+
+while(<AMDUMP>) {
+       chomp;
+       if(/(amdump|amflush): start at (.*)/) {
+               print " from $2";
+               $starttime=&unctime(split(/[    ]+/,$2));
+       }
+       elsif(/amdump: datestamp (\S+)/) {
+               $gdatestamp = $1;
+               if(!defined $datestamp{$gdatestamp}) {
+                       $datestamp{$gdatestamp} = 1;
+                       push @datestamp, $gdatestamp;
+               }
+       }
+       elsif(/setup_estimate: (\S+):(\S+): command .*, options:/) {
+               $host=$1;
+               $partition=$2;
+               $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+               $estimate{$hostpart}=0;
+               $level{$hostpart}=0;
+               $esize{$hostpart}=0;
+               $dump_started{$hostpart}=0;
+               $dump_finished{$hostpart}=0;
+               $taper_started{$hostpart}=0;
+               $taper_finished{$hostpart}=0;
+               $error{$hostpart}="";
+       }
+       elsif(/got result for host (\S+) disk (\S+): (\d+) -> (\d+)K,/) {
+               $host=$1;
+               $partition=$2;
+               $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+               $estimate{$hostpart}=1;
+               $level{$hostpart}=$3;
+               $esize{$hostpart}=$4;
+       }
+       elsif(/getting estimates took/) {
+               $estimate_done=1;
+       }
+       elsif(/amflush/) {
+               $estimate_done=1;
+       }
+       elsif(/GENERATING SCHEDULE:/) {
+               $generating_schedule=1;
+       }
+       elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
+               if($generating_schedule == 1 ) {
+                       $host=$1;
+                       $partition=$2;
+                       $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+                       $level{"$hostpart"}=$4;
+                       $esize=$5;
+                       $esize=32 if $esize<32;
+                       $esize{$hostpart}=$esize;
+                       $degr_level{$hostpart}=-1;
+               }
+       }
+       elsif(/^DUMP (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
+               if($generating_schedule == 1 ) {
+                       $host=$1;
+                       $partition=$2;
+                       $datestamp=$3;
+                       $hostpart=&make_hostpart($host,$partition,$datestamp);
+                       $level{"$hostpart"}=$5;
+                       $esize=$6;
+                       $esize=32 if $esize<32;
+                       $esize{$hostpart}=$esize;
+                       $degr_level{$hostpart}=-1;
+               }
+       }
+       elsif(/^DUMP (\S+) (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
+               if($generating_schedule == 1 ) {
+                       $host=$1;
+                       $features=$2;
+                       $features=$features;
+                       $partition=$3;
+                       $datestamp=$4;
+                       $hostpart=&make_hostpart($host,$partition,$datestamp);
+                       $level{"$hostpart"}=$6;
+                       $esize=$7;
+                       $esize=32 if $esize<32;
+                       $esize{$hostpart}=$esize;
+                       $degr_level{$hostpart}=-1;
+               }
+       }
+       elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+ (\d+) \d+:\d+:\d+:\d+:\d+:\d+ ([-]*\d+) \d+/) {
+               if($generating_schedule == 1 ) {
+                       $host=$1;
+                       $partition=$2;
+                       $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+                       $level{$hostpart}=$4;
+                       $esize=$5;
+                       $esize=32 if $esize<32;
+                       $esize{$hostpart}=$esize;
+                       $degr_level{$hostpart}=$6;
+                       $degr_size{$hostpart}=$7;
+                       $degr_size{$hostpart}=32 if ($7 < 32);
+               }
+       }
+       elsif(/^DUMP (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+ (\d+) \d+:\d+:\d+:\d+:\d+:\d+ ([-]*\d+) \d+/) {
+               if($generating_schedule == 1 ) {
+                       $host=$1;
+                       $partition=$2;
+                       $datestamp=$3;
+                       $hostpart=&make_hostpart($host,$partition,$datestamp);
+                       $level{$hostpart}=$5;
+                       $esize=$6;
+                       $esize=32 if $esize<32;
+                       $esize{$hostpart}=$esize;
+                       $degr_level{$hostpart}=$7;
+                       $degr_size{$hostpart}=$8;
+                       $degr_size{$hostpart}=32 if ($8 < 32);
+               }
+       }
+       elsif(/^FLUSH (\S+) (\S+) (\S+) (\d+) (\S+)/) {
+               $host=$1;
+               $partition=$2;
+               $datestamp=$3;
+               $level=$4;
+               $holding_file=$5;
+               $hostpart=&make_hostpart($host,$partition,$datestamp);
+               $flush{$hostpart}=0;
+               $holding_file{$hostpart}=$holding_file;
+               $level{$hostpart}=$level;
+       }
+       elsif(/^driver: start time (\S+)/) {
+               $start_time=$1;
+               $current_time=$1;
+               $dumpers_active[0]=0;
+               $dumpers_held[0]={};
+               $dumpers_active=0;
+       }
+       elsif(/^driver: tape size (\d+)/) {
+               $tape_size = $1;
+       }
+       elsif(/^driver: adding holding disk \d+ dir \S+ size (\d+)/) {
+               $holding_space += $1;
+       }
+       elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\d+)/) {
+               $current_time=$1;
+               $host=$6;
+               $partition=$7;
+               $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+               $serial=$4;
+               $serial{$serial}=$hostpart;
+               $dump_started{$hostpart}=1;
+               $dump_time{$hostpart}=$1;
+               $dump_finished{$hostpart}=0;
+               $holding_file{$hostpart}=$5;
+               if(     $level{$hostpart} != $8 &&
+                  $degr_level{$hostpart} == $8) {
+                       $level{$hostpart}=$degr_level{$hostpart};
+                       $esize{$hostpart}=$degr_size{$hostpart};
+               }
+               if(! defined($busy_time{$2})) {
+                       $busy_time{$2}=0;
+               }
+               $running_dumper{$2} = $hostpart;
+               $error{$hostpart}="";
+               $dumpers_active++;
+               if(! defined($dumpers_active[$dumpers_active])) {
+                       $dumpers_active[$dumpers_active]=0;
+               }
+               if(! defined($dumpers_held[$dumpers_active])) {
+                       $dumpers_held[$dumpers_active]={};
+               }
+       }
+       elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
+               $current_time=$1;
+               $host=$6;
+               $partition=$7;
+               $device=$8;
+               $device=$device;
+               $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+               $serial=$4;
+               $serial{$serial}=$hostpart;
+               $dump_started{$hostpart}=1;
+               $dump_time{$hostpart}=$1;
+               $dump_finished{$hostpart}=0;
+               $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
+               if(     $level{$hostpart} != $9 &&
+                  $degr_level{$hostpart} == $9) {
+                       $level{$hostpart}=$degr_level{$hostpart};
+                       $esize{$hostpart}=$degr_size{$hostpart};
+               }
+               if(! defined($busy_time{$2})) {
+                       $busy_time{$2}=0;
+               }
+               $running_dumper{$2} = $hostpart;
+               $error{$hostpart}="";
+               $dumpers_active++;
+               if(! defined($dumpers_active[$dumpers_active])) {
+                       $dumpers_active[$dumpers_active]=0;
+               }
+               if(! defined($dumpers_held[$dumpers_active])) {
+                       $dumpers_held[$dumpers_active]={};
+               }
+       }
+       elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
+               $current_time=$1;
+               $host=$6;
+               $features=$7;
+               $features=$features;
+               $partition=$8;
+               $device=$9;
+               $device=$device;
+               $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+               $serial=$4;
+               $serial{$serial}=$hostpart;
+               $dump_started{$hostpart}=1;
+               $dump_time{$hostpart}=$1;
+               $dump_finished{$hostpart}=0;
+               $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
+               if(     $level{$hostpart} != $10 &&
+                  $degr_level{$hostpart} == $10) {
+                       $level{$hostpart}=$degr_level{$hostpart};
+                       $esize{$hostpart}=$degr_size{$hostpart};
+               }
+               if(! defined($busy_time{$2})) {
+                       $busy_time{$2}=0;
+               }
+               $running_dumper{$2} = $hostpart;
+               $error{$hostpart}="";
+               $dumpers_active++;
+               if(! defined($dumpers_active[$dumpers_active])) {
+                       $dumpers_active[$dumpers_active]=0;
+               }
+               if(! defined($dumpers_held[$dumpers_active])) {
+                       $dumpers_held[$dumpers_active]={};
+               }
+       }
+       elsif(/driver: result time (\S+) from (dumper\d+): FAILED (\d+-\d+) (.*)/) {
+               $current_time=$1;
+               $serial=$3;
+               $error=$4;
+               $hostpart=$serial{$serial};
+               $dump_finished{$hostpart}=-1;
+               $busy_time{$2}+=($1-$dump_time{$hostpart});
+               $running_dumper{$2} = "0";
+               $dump_time{$hostpart}=$1;
+               $error{$hostpart}="driver: $error";
+               $dumpers_active--;
+       }
+       elsif(/driver: result time (\S+) from (dumper\d+): TRY-AGAIN (\d+-\d+) (.*)/) {
+               $current_time=$1;
+               $serial=$3;
+               $error=$4;
+               $hostpart=$serial{$serial};
+               $dump_started{$hostpart}=0;
+               $dump_finished{$hostpart}=0;
+               $busy_time{$2}+=($1-$dump_time{$hostpart});
+               $running_dumper{$2} = "0";
+               $dump_time{$hostpart}=$1;
+               $error{$hostpart}="driver: (aborted:$error)";
+               $dumpers_active--;
+       }
+       elsif(/driver: result time (\S+) from (dumper\d+): DONE (\d+-\d+) (\d+) (\d+) (\d+) \[.*\]/) {
+               $current_time=$1;
+               $serial=$3;
+               $origsize=$4;
+               $outputsize=$5;
+               $hostpart=$serial{$serial};
+               $size{$hostpart}=$outputsize;
+               $dump_finished{$hostpart}=1;
+               $busy_time{$2}+=($1-$dump_time{$hostpart});
+               $running_dumper{$2} = "0";
+               $dump_time{$hostpart}=$1;
+               $error{$hostpart}="";
+               $dumpers_active--;
+       }
+       elsif(/driver: result time (\S+) from (dumper\d+): ABORT-FINISHED (\d+-\d+)/) {
+               $current_time=$1;
+               $serial=$3;
+               $hostpart=$serial{$serial};
+               $dump_started{$hostpart}=0;
+               $dump_finished{$hostpart}=0;
+               $busy_time{$2}+=($1-$dump_time{$hostpart});
+               $running_dumper{$2} = "0";
+               $dump_time{$hostpart}=$1;
+               $error{$hostpart}="driver: (aborted)";
+               $dumpers_active--;
+       }
+       elsif(/driver: finished-cmd time (\S+) dumper\d+ dumped (\S+):(\S+)/){
+               $current_time=$1;
+       }
+       elsif(/driver: send-cmd time (\S+) to taper: START-TAPER (\S+)/) {
+               if(!defined $gdatestamp) {
+                       $gdatestamp=$2;
+                       if(!defined $datestamp{$gdatestamp}) {
+                               $datestamp{$gdatestamp} = 1;
+                               push @datestamp, $gdatestamp;
+                       }
+               }
+       }
+       elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S+) (\d*) (\S+)/){
+               $current_time=$1;
+               $serial=$2;
+               $host=$4;
+               $partition=$5;
+               $level=$6;
+               $ldatestamp=$7;
+               if(!defined $datestamp{$ldatestamp}) {
+                       $datestamp{$ldatestamp} = 1;
+                       push @datestamp, $ldatestamp;
+               }
+               $hostpart=&make_hostpart($host,$partition,$ldatestamp);
+               $serial{$serial}=$hostpart;
+               if(!defined $level{$hostpart}) {
+                       $level{$hostpart} = $level;
+               }
+               $serial{$serial}=$hostpart;
+               $taper_started{$hostpart}=1;
+               $taper_finished{$hostpart}=0;
+               $taper_time{$hostpart}=$1;
+       }
+       #features (maybe missing features)
+       elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S*) (\S+) (\d*) (\S+)/){
+               $current_time=$1;
+               $serial=$2;
+               $host=$4;
+               $features=$5;
+               $features=$features;
+               $partition=$6;
+               $level=$7;
+               $ldatestamp=$8;
+               if(!defined $datestamp{$ldatestamp}) {
+                       $datestamp{$ldatestamp} = 1;
+                       push @datestamp, $ldatestamp;
+               }
+               $hostpart=&make_hostpart($host,$partition,$ldatestamp);
+               $serial{$serial}=$hostpart;
+               if(!defined $level{$hostpart}) {
+                       $level{$hostpart} = $level;
+               }
+               $serial{$serial}=$hostpart;
+               $taper_started{$hostpart}=1;
+               $taper_finished{$hostpart}=0;
+               $taper_time{$hostpart}=$1;
+       }
+       elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) \d+( \d+|)/){
+               $current_time=$1;
+               $serial=$2;
+               $host=$3;
+               $partition=$4;
+               $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+               $serial{$serial}=$hostpart;
+               $taper_started{$hostpart}=1;
+               $taper_finished{$hostpart}=0;
+               $taper_time{$hostpart}=$1;
+       }
+       elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) (\S+) \d+ \d+/){
+               $current_time=$1;
+               $serial=$2;
+               $host=$3;
+               $features=$4;
+               $partition=$5;
+               $hostpart=&make_hostpart($host,$partition,$gdatestamp);
+               $serial{$serial}=$hostpart;
+               $taper_started{$hostpart}=1;
+               $taper_finished{$hostpart}=0;
+               $taper_time{$hostpart}=$1;
+       }
+       elsif(/driver: result time (\S+) from taper: DONE (\d+-\d+) (\S+) (\d+) \[sec (\S+) kb (\d+) kps/) {
+               $current_time=$1;
+               $serial=$2;
+               $label=$3;
+               $size=$6;
+               $hostpart=$serial{$serial};
+               $taper_finished{$hostpart}=1;
+               $busy_time{"taper"}+=($1-$taper_time{$hostpart});
+               $taper_time{$hostpart}=$1;
+               if(!defined $size{$hostpart}) {
+                       $size{$hostpart}=$size;
+               }
+               $ntpartition{$nb_tape}++;
+               $ntsize{$nb_tape} += $size{$hostpart};
+               if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
+                       $ntesize{$nb_tape} += $esize{$hostpart};
+               }
+               else {
+                       $ntesize{$nb_tape} += $size{$hostpart};
+               }
+       }
+       elsif(/driver: result time (\S+) from taper: (TRY-AGAIN|TAPE-ERROR) (\d+-\d+) (.+)/) {
+               $current_time=$1;
+               $serial=$3;
+               $error=$4;
+               $hostpart=$serial{$serial};
+               $taper_finished{$hostpart}= $2 eq 'TAPE-ERROR' ? -2 : -1;
+               $busy_time{"taper"}+=($1-$taper_time{$hostpart});
+               $taper_time{$hostpart}=$1;
+               $error{$hostpart}="driver: $error";
+       }
+       elsif(/planner: FAILED (\S+) (\S+) (\S+) (\d+) (.*)/) {
+               $host=$1;
+               $partition=$2;
+               $datestamp=$3;
+               $hostpart=&make_hostpart($host,$partition,$datestamp);
+               $dump_started{$hostpart}=-1;
+               $level{$hostpart}=$4;
+               $error{$hostpart}="planner: $5";
+       }
+       elsif(/dump of driver schedule after start degraded mode:/) {
+               $start_degraded_mode=1;
+       }
+       elsif(/driver: state time (\S+) free (.*) taper: (\S+) idle-dumpers: (\d+) qlen (.*) driver-idle: (\S+)/) {
+               $current_time=$1;
+               $status_taper=$3;
+               $idle_dumpers=$4;
+
+               %free = split (/ +/, $2);
+               %qlen = split (/ +/, $5);
+
+               if($status_driver ne "") {
+                       $dumpers_active[$dumpers_active_prev]
+                               +=$current_time-$state_time_prev;
+                       $dumpers_held[$dumpers_active_prev]{$status_driver}
+                               +=$current_time-$state_time_prev;
+               }
+               $state_time_prev=$current_time;
+               $dumpers_active_prev=$dumpers_active;
+               $status_driver=$6;
+               if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
+                       $dumpers_held[$dumpers_active]{$status_driver}=0;
+               }
+       }
+       elsif(/taper: wrote label `(\S*)'/) {
+               $nb_tape++;
+               $ntlabel{$nb_tape} = $1;
+               $ntpartition{$nb_tape} = 0;
+               $ntsize{$nb_tape} = 0;
+               $ntesize{$nb_tape} = 0;
+       }
+}
+
+close(AMDUMP);
+
+if(defined $current_time) {
+       for ($d = 0; $d < $#dumpers_active; $d++) {
+               $the_dumper = "dumper$d";
+               if(defined($running_dumper{$the_dumper}) &&
+                  $running_dumper{$the_dumper} ne "0") {
+                       $busy_time{$the_dumper}+=($current_time-$dump_time{$running_dumper{$the_dumper}});
+               }
+       }
+}
+
+print "\n\n";
+
+$nb_partition = 0;
+
+$epartition = 0;
+$estsize = 0;
+$fpartition = 0;
+$fsize = 0;
+$wpartition = 0;
+$wsize = 0;
+
+$flpartition = 0;
+$flsize = 0;
+$wfpartition = 0;
+$wfsize = 0;
+
+$dtpartition = 0;
+$dtesize = 0;
+$dupartition = 0;
+$dusize = 0;
+$duesize = 0;
+$dpartition = 0;
+$dsize = 0;
+$desize = 0;
+
+$twpartition = 0;
+$twsize = 0;
+$twesize = 0;
+$tapartition = 0;
+$tasize = 0;
+$taesize = 0;
+$tfpartition = 0;
+$tfsize = 0;
+$tfesize = 0;
+$tpartition = 0;
+$tsize = 0;
+$tesize = 0;
+
+$maxnamelength = 10;
+foreach $host (sort @hosts) {
+       foreach $partition (sort @$host) {
+               foreach $datestamp (sort @datestamp) {
+                       $hostpart=&make_hostpart($host,$partition,$datestamp);
+                       next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
+                       if(length("$host:$partition") > $maxnamelength) {
+                               $maxnamelength = length("$host:$partition");
+                       }
+               }
+       }
+}
+
+foreach $host (sort @hosts) {
+       foreach $partition (sort @$host) {
+          foreach $datestamp (sort @datestamp) {
+                       $hostpart=&make_hostpart($host,$partition,$datestamp);
+                       next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
+                       $nb_partition++;
+                       if( !defined $size{$hostpart} && defined $holding_file{$hostpart}) {
+                               $size{$hostpart} = &dump_size($holding_file{$hostpart}) / 1024;
+                       }
+                       $in_flush=0;
+                       if($estimate_done != 1) {
+                               if(defined $estimate{$hostpart}) {
+                                       if($estimate{$hostpart} != 1) {
+                                               if( defined $opt_gestimate) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s", "$host:$partition";
+                                                       print "             getting estimate\n";
+                                               }
+                                       }
+                                       else {
+                                               if(defined $opt_estimate) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s", "$host:$partition";
+                                                       printf "%2d",  $level{$hostpart};
+                                                       printf "%9dk", $esize{$hostpart};
+                                                       print " estimate done\n";
+                                               }
+                                               $epartition++;
+                                               $estsize += $esize{$hostpart};
+                                       }
+                               }
+                       }
+                       else {
+                               if(defined $estimate{$hostpart}) {
+                                       if($estimate{$hostpart} == 1) {
+                                               $epartition++;
+                                               $estsize += $esize{$hostpart};
+                                       }
+                                       elsif (!defined $dump_started{$hostpart} || $dump_started{$hostpart} == 0) {
+                                               if( defined $opt_failed) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf "           no estimate\n";
+                                               }
+                                               $fpartition++;
+                                       }
+                               }
+                               else {
+                                       $flpartition++;
+                                       $flsize += $size{$hostpart};
+                                       $in_flush=1;
+                               }
+                               if(defined $taper_started{$hostpart} &&
+                                               $taper_started{$hostpart}==1) {
+                                       if(defined $dump_started{$hostpart}) {
+                                               $dpartition++;
+                                               if(defined($size{$hostpart})) {
+                                                       $dsize += $size{$hostpart};
+                                               }
+                                               else {
+                                                       $dsize += $esize{$hostpart};
+                                               }
+                                               $desize += $esize{$hostpart};
+                                       }
+                                       if(defined $dump_started{$hostpart} &&
+                                               $dump_started{$hostpart} == 1 &&
+                                                       $dump_finished{$hostpart} == 0 &&
+                                                       $taper_started{$hostpart} == 1) {
+                                               if( defined $opt_dumpingtape ) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf "%9dk", $esize{$hostpart};
+                                                       print " dumping to tape";
+                                                       if( defined $starttime ) {
+                                                               print " (", &showtime($taper_time{$hostpart}), ")";
+                                                       }
+                                                       print "\n";
+                                               }
+                                               $dtpartition++;
+                                               $dtesize += $esize{$hostpart};
+                                       }
+                                       elsif($taper_finished{$hostpart} == 0) {
+                                               if( defined $opt_writingtape ) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf "%9dk", $size{$hostpart};
+                                                       if($in_flush == 0) {
+                                                               print " writing to tape";
+                                                       }
+                                                       else {
+                                                               print " flushing to tape";
+                                                       }
+                                                       if( defined $starttime ) {
+                                                               print " (", &showtime($taper_time{$hostpart}), ")";
+                                                       }
+                                                       print "\n";
+                                               }
+                                               $tapartition++;
+                                               $tasize += $size{$hostpart};
+                                               if(defined $esize{$hostpart}) {
+                                                       $taesize += $esize{$hostpart};
+                                               }
+                                               else {
+                                                       $taesize += $size{$hostpart};
+                                               }
+                                       }
+                                       elsif($taper_finished{$hostpart} < 0) {
+                                               if( defined $opt_failed  ||
+                                                        (defined $opt_waittaper && ($taper_finished{$hostpart} == -1))) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf "%9dk", $size{$hostpart};
+                                                       if($in_flush == 0) {
+                                                               print " failed to tape";
+                                                       }
+                                                       else {
+                                                               print " failed to flush";
+                                                       }
+                                                       print " (will retry)" unless $taper_finished{$hostpart} < -1;
+                                                       if( defined $starttime ) {
+                                                               print " (", &showtime($taper_time{$hostpart}), ")";
+                                                       }
+                                                       print "\n";
+                                               }
+
+                                               $tfpartition++;
+                                               $tfsize += $size{$hostpart};
+                                               if(defined $esize{$hostpart}) {
+                                                       $tfesize += $esize{$hostpart};
+                                               }
+                                               else {
+                                                       $tfesize += $size{$hostpart};
+                                               }
+
+                                               if($in_flush == 0) {
+                                                       $twpartition++;
+                                                       $twsize += $size{$hostpart};
+                                                       if(defined $esize{$hostpart}) {
+                                                               $twesize += $esize{$hostpart};
+                                                       }
+                                                       else {
+                                                               $twesize += $size{$hostpart};
+                                                       }
+                                               }
+                                               else {
+                                                       $wfpartition++;
+                                                       $wfsize += $size{$hostpart};
+                                                       if(defined $esize{$hostpart}) {
+                                                               $wfesize += $esize{$hostpart};
+                                                       }
+                                                       else {
+                                                               $wfesize += $size{$hostpart};
+                                                       }
+                                               }
+                                       }
+                                       elsif($taper_finished{$hostpart} == 1) {
+                                               if( defined $opt_finished ) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf "%9dk", $size{$hostpart};
+                                                       if($in_flush == 0) {
+                                                               print " finished";
+                                                       }
+                                                       else {
+                                                               print " flushed";
+                                                       }
+                                                       if( defined $starttime ) {
+                                                               print " (", &showtime($taper_time{$hostpart}), ")";
+                                                       }
+                                                       print "\n";
+                                               }
+                                               $tpartition++;
+                                               $tsize += $size{$hostpart};
+                                               if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
+                                                       $tesize += $esize{$hostpart};
+                                               }
+                                               else {
+                                                       $tesize += $size{$hostpart};
+                                               }
+                                       }
+                                       else {
+                                               printf "%8s ", $datestamp if defined $opt_date;
+                                               printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                               print " unknown state TAPER\n";
+                                       }
+                               }
+                               elsif(defined $dump_started{$hostpart}) {
+                                       if($dump_started{$hostpart} == -1) {
+                                               if( defined $opt_failed ) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf " " . $error{$hostpart} . "\n";
+                                               }
+                                               $fpartition++;
+                                               $fsize+=$esize{$hostpart};
+                                       }
+                                       elsif($dump_started{$hostpart} == 0) {
+                                               if($estimate{$hostpart} == 1) {
+                                                       if( defined $opt_waitdumping ) {
+                                                               printf "%8s ", $datestamp if defined $opt_date;
+                                                               printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                               printf "%9dk", $esize{$hostpart};
+                                                               print " wait for dumping $error{$hostpart}\n";
+                                                       }
+                                                       $wpartition++;
+                                                       $wsize += $esize{$hostpart};
+                                               }
+                                       }
+                                       elsif($dump_started{$hostpart} == 1 &&
+                                                       $dump_finished{$hostpart} == -1) {
+                                               if( defined $opt_failed ) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       print " ", $error{$hostpart};
+                                                       if( defined $starttime ) {
+                                                               print " (", &showtime($dump_time{$hostpart}), ")";
+                                                       }
+                                                       print "\n";
+                                               }
+                                               $fpartition++;
+                                               $fsize+=$esize{$hostpart};
+                                       }
+                                       elsif($dump_started{$hostpart} == 1 &&
+                                                       $dump_finished{$hostpart} != 1) {
+                                               if( defined $opt_dumping ) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf "%9dk", $esize{$hostpart};
+                                                       printf " dumping %8dk", $size{$hostpart};
+                                                       if($size{$hostpart} != 0) {
+                                                               printf " (%6.2f%%)", (100.0*$size{$hostpart})/$esize{$hostpart};
+                                                       }
+                                                       if( defined $starttime ) {
+                                                               print " (", &showtime($dump_time{$hostpart}), ")";
+                                                       }
+                                                       print "\n";
+                                               }
+                                               $dupartition++;
+                                               $dusize += $size{$hostpart};
+                                               $duesize += $esize{$hostpart};
+                                       }
+                                       elsif($dump_finished{$hostpart} == 1 &&
+                                                       $taper_started{$hostpart} != 1) {
+                                               if( defined $opt_waittaper ) {
+                                                       printf "%8s ", $datestamp if defined $opt_date;
+                                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                                       printf "%9dk", $size{$hostpart};
+                                                       print " dump done";
+                                                       if( defined $starttime ) {
+                                                               print " (", &showtime($dump_time{$hostpart}), ")";
+                                                       }
+                                                       print ", wait for writing to tape\n";
+                                               }
+                                               $dpartition++;
+                                               $dsize += $size{$hostpart};
+                                               $desize += $esize{$hostpart};
+                                               $twpartition++;
+                                               $twsize += $size{$hostpart};
+                                               $twesize += $esize{$hostpart};
+                                       }
+                                       else {
+                                               printf "%8s ", $datestamp if defined $opt_date;
+                                               printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                               print " unknown state DUMPER\n";
+                                       }
+                               }
+                               elsif(defined $flush{$hostpart}) {
+                                       if( defined $opt_waittaper ) {
+                                               printf "%8s ", $datestamp if defined $opt_date;
+                                               printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                               printf "%9dk", $size{$hostpart};
+                                               print " waiting to flush\n";
+                                       }
+                                       $wfpartition++;
+                                       $wfsize += $size{$hostpart};
+                               }
+                               elsif(defined $level{$hostpart}) {
+                                       printf "%8s ", $datestamp if defined $opt_date;
+                                       printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
+                                       print " unknown state\n";
+                               }
+                       }
+               }
+       }
+}
+
+if (defined $opt_summary) {
+       print "\n";
+       print  "SUMMARY          part      real  estimated\n";
+       print  "                           size       size\n";
+       printf "partition       : %3d\n", $nb_partition;
+       printf "estimated       : %3d %20dk\n", $epartition , $estsize;
+       printf "flush           : %3d %9dk\n", $flpartition, $flsize;
+       printf "failed          : %3d %20dk           (%6.2f%%)\n",
+               $fpartition , $fsize,
+               $estsize ? ($fsize * 1.0 / $estsize) * 100 : 0.0;
+       printf "wait for dumping: %3d %20dk           (%6.2f%%)\n",
+               $wpartition , $wsize,
+               $estsize ? ($wsize * 1.0 / $estsize) * 100 : 0.0;
+       printf "dumping to tape : %3d %20dk           (%6.2f%%)\n",
+               $dtpartition, $dtesize,
+               $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
+       printf "dumping         : %3d %9dk %9dk (%6.2f%%) (%6.2f%%)\n",
+               $dupartition, $dusize, $duesize,
+               $duesize ? ($dusize * 1.0 / $duesize) * 100 : 0.0,
+               $estsize ? ($dusize * 1.0 / $estsize) * 100 : 0.0;
+       printf "dumped          : %3d %9dk %9dk (%6.2f%%) (%6.2f%%)\n",
+               $dpartition , $dsize , $desize,
+               $desize ? ($dsize * 1.0 / $desize) * 100 : 0.0,
+               $estsize ? ($dsize * 1.0 / $estsize) * 100 : 0.0;
+       printf "wait for writing: %3d %9dk %9dk (%6.2f%%) (%6.2f%%)\n",
+               $twpartition, $twsize, $twesize,
+               $twesize ? ($twsize * 1.0 / $twesize) * 100 : 0.0,
+               $estsize ? ($twsize * 1.0 / $estsize) * 100 : 0.0;
+       printf "wait to flush   : %3d %9dk %9dk (%6.2f%%) (%6.2f%%)\n",
+               $wfpartition, $wfsize, $wfsize, 100, 0;
+       printf "writing to tape : %3d %9dk %9dk (%6.2f%%) (%6.2f%%)\n",
+               $tapartition, $tasize, $taesize,
+               $taesize ? ($tasize * 1.0 / $taesize) * 100 : 0.0,
+               $estsize ? ($tasize * 1.0 / $estsize) * 100 : 0.0;
+       printf "failed to tape  : %3d %9dk %9dk (%6.2f%%) (%6.2f%%)\n",
+               $tfpartition, $tfsize, $tfesize,
+               $tfesize ? ($tfsize * 1.0 / $tfesize) * 100 : 0.0,
+               $estsize ? ($tfsize * 1.0 / $estsize) * 100 : 0.0;
+       printf "taped           : %3d %9dk %9dk (%6.2f%%) (%6.2f%%)\n",
+               $tpartition , $tsize , $tesize,
+               $tesize ? ($tsize * 1.0 / $tesize) * 100 : 0.0,
+               ($estsize+$flsize) ? ($tsize * 1.0 / ($estsize + $flsize)) * 100 : 0.0;
+       if($nb_tape > 1 || $tape_size != 0) {
+               for($i=1; $i <= $nb_tape; $i++) {
+                       if($tape_size != 0) {
+                               printf "  tape %-3d      : %3d %9dk %9dk (%6.2f%%) %s\n",
+                                       $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, 100*$ntsize{$i}/$tape_size, $ntlabel{$i};
+                       }
+                       else {
+                               printf "  tape %-3d      : %3d %9dk %9dk %s\n",
+                                       $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, $ntlabel{$i};
+                       }
+               }
+       }
+       if($idle_dumpers ==0) {
+               printf "all dumpers active\n";
+       }
+       else {
+               $c1 = ($idle_dumpers == 1) ? "" : "s";
+               $c2 = ($idle_dumpers < 10) ? " " : "";
+               $c3 = ($idle_dumpers == 1) ? " " : "";
+               printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
+       }
+       if($status_taper eq "writing" && defined($qlen{"tapeq:"})) {
+               printf "taper writing, tapeq: %d\n", $qlen{"tapeq:"};
+       }
+       else {
+               printf "taper idle\n";
+       }
+       if (defined ($free{"kps:"})) {
+               printf "network free kps: %9d\n", $free{"kps:"};
+       }
+       if (defined ($free{"space:"})) {
+               if ($holding_space) {
+                       $hs = ($free{"space:"} * 1.0 / $holding_space) * 100;
+               } else {
+                       $hs = 0.0;
+               }
+               printf "holding space   : %9dk (%6.2f%%)\n", $free{"space:"}, $hs;
+       }
+}
+
+if(defined $opt_stats) {
+       if(defined($current_time) && $current_time != $start_time) {
+               $total_time=$current_time-$start_time;
+               foreach $key (sort byprocess keys %busy_time) {
+                       printf "%8s busy   : %8s  (%6.2f%%)\n",
+                               $key, &busytime($busy_time{$key}),
+                               ($busy_time{$key} * 1.0 / $total_time) * 100;
+               }
+               for ($d = 0; $d <= $#dumpers_active; $d++) {
+                       $l = sprintf "%2d dumper%s busy%s : %8s  (%6.2f%%)",
+                               $d, ($d == 1) ? "" : "s", ($d == 1) ? " " : "",
+                               &busytime($dumpers_active[$d]),
+                               ($dumpers_active[$d] * 1.0 / $total_time) * 100;
+                       print $l;
+                       $s1 = "";
+                       $s2 = " " x length($l);
+                       $r = $dumpers_held[$d];
+                       foreach $key (sort valuesort keys %$r) {
+                               next
+                                 unless $dumpers_held[$d]{$key} >= 1;
+                               printf "%s%20s: %8s  (%6.2f%%)\n",
+                                       $s1,
+                                       $key,
+                                       &busytime($dumpers_held[$d]{$key}),
+                                       ($dumpers_held[$d]{$key} * 1.0 / $dumpers_active[$d]) * 100;
+                               $s1 = $s2;
+                       }
+                       if ($s1 eq "") {
+                               print "\n";
+                       }
+               }
+       }
+}
+
+sub make_hostpart() {
+       local($host,$partition,$datestamp) = @_;
+
+       if(! defined($hosts{$host})) {
+               push @hosts, $host;
+               $hosts{$host}=1;
+       }
+       my($new_part) = 1;
+       foreach $pp (sort @$host) {
+               $new_part = 0 if ($pp eq $partition);
+       }
+       push @$host, $partition if $new_part==1;
+
+       my($hostpart) = "$host$partition$datestamp";
+       if(!defined $datestamp{$datestamp}) {
+               $datestamp{$datestamp} = 1;
+               push @datestamp, $datestamp;
+       }
+       return $hostpart;
+}
+
+sub byprocess() {
+       my(@tmp_a) = split(/(\d*)$/, $a, 2);
+       my(@tmp_b) = split(/(\d*)$/, $b, 2);
+       return ($tmp_a[0] cmp $tmp_b[0]) || ($tmp_a[1] <=> $tmp_b[1]);
+}                               
+sub valuesort() {
+       $r->{$b} <=> $r->{$a};
+}
+
+sub dump_size() {
+       local($filename) = @_;
+       local($size);
+       local($dsize) = 0;
+       local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+                  $atime,$mtime,$ctime,$blksize,$blocks);
+       while ($filename ne "") {
+               $filename = "$filename.tmp" if (!(-e "$filename"));
+               $filename = "/dev/null" if (!(-e "$filename"));
+               ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+                               $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
+               $size=$size-32768 if $size > 32768;
+               $dsize += $size;
+               open(DUMP,$filename);
+               $filename = "";
+               while(<DUMP>) {
+                       if(/^CONT_FILENAME=(.*)$/) { $filename = $1; last }
+                       last if /^To restore, position tape at start of file and run/;
+               }
+               close(DUMP);
+       }
+       return $dsize;
+}
+
+sub unctime() {
+       my (@MoY);
+       my (@tl);
+       my ($a);
+       my ($m);
+       my ($month);
+       my ($time);
+
+       @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
+               'Jul','Aug','Sep','Oct','Nov','Dec');
+
+       # Preset an array of values in case some parts are not passed as
+       # arguments.  This lets the date, etc, be omitted and default to
+       # today.
+
+       @tl = localtime;
+
+       foreach $a (@_) {
+               next
+                 if ($a eq '');
+
+               # See if this argument looks like a month name.
+
+               $month = 0;
+               foreach $m (@MoY) {
+                       last
+                         if ($m eq $a);
+                       $month = $month + 1;
+               }
+               if ($month < 12) {
+                       $tl[4] = $month;
+                       next;
+               }
+
+               # See if this is a day of the month.
+
+               if ($a =~ /^\d+$/ && $a >= 1 && $a <= 32) {
+                       $tl[3] = $a;
+                       next;
+               }
+
+               # See if the next argument looks like a time.
+
+               if ($a =~ /^(\d+):(\d+)/) {
+                       $tl[2] = $1;
+                       $tl[1] = $2;
+                       if ($a =~ /^(\d+):(\d+):(\d+)/) {
+                               $tl[0] = $3;
+                       }
+                       next;
+               }
+
+               # See if this is a year.
+
+               if ($a =~ /^\d\d\d\d$/ && $a >= 1900) {
+                       $tl[5] = $a;
+                       next;
+               }
+       }
+
+       $time = &timelocal (@tl);
+
+       return $time;
+}
+
+sub showtime() {
+       my($delta)=shift;
+       my($oneday)=24*60*60;
+
+       @now=localtime($starttime+$delta);
+       if($delta > $oneday) {
+               $result=sprintf("%d+",$delta/$oneday);
+       } else {
+               $result="";
+       }
+       $result.=sprintf("%d:%02d:%02d",$now[2],$now[1],$now[0]);
+       return $result;
+}
+
+sub busytime() {
+       my($busy)=shift;
+       my($oneday)=24*60*60;
+
+       if($busy > $oneday) {
+               $days=int($busy/$oneday);
+               $result=sprintf("%d+",$busy/$oneday);
+               $busy-=$days*$oneday;
+       } else {
+               $result="";
+       }
+       $hours=int($busy/60/60);
+       $busy-=$hours*60*60;
+       $minutes=int($busy/60);
+       $busy-=$minutes*60;
+       $seconds=$busy;
+       $result.=sprintf("%d:%02d:%02d",$hours,$minutes,$seconds);
+       return $result;
+}
+
+sub usage() {
+       print "amstatus [--config] config [--file amdump_file]\n";
+       print "         [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
+       print "         [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
+       print "         [--estimate] [--gestimate] [--stats] [--date]\n";
+       exit 0;
+}
diff --git a/server-src/amtape.c b/server-src/amtape.c
new file mode 100644 (file)
index 0000000..9c0f7f5
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ * 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: amtape.c,v 1.22.2.6.4.5.2.4 2003/11/25 12:21:08 martinea Exp $
+ *
+ * tape changer interface program
+ */
+#include "amanda.h"
+#include "conffile.h"
+#include "tapefile.h"
+#include "tapeio.h"
+#include "clock.h"
+#include "changer.h"
+#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 taper_scan P((int argc, char **argv));
+void show_device P((int argc, char **argv));
+int scan_init P((int rc, int ns, int bk));
+int loadlabel_slot P((int rc, char *slotstr, char *device));
+int show_init P((int rc, int ns, int bk));
+int show_init_all P((int rc, int ns, int bk));
+int show_init_current P((int rc, int ns, int bk));
+int show_slot P((int rc, char *slotstr, char *device));
+int taperscan_slot P((int rc, char *slotstr, char *device));
+int update_one_slot P((int rc, char *slotstr, char *device));
+void update_labeldb P((int argc, char **argv));
+
+void usage()
+{
+    fprintf(stderr, "Usage: amtape%s <conf> <command>\n", versionsuffix());
+    fprintf(stderr, "\tValid commands are:\n");
+    fprintf(stderr, "\t\treset                Reset changer to known state\n");
+    fprintf(stderr, "\t\teject                Eject current tape from drive\n");
+    fprintf(stderr, "\t\tclean                Clean the drive\n");
+    fprintf(stderr, "\t\tshow                 Show contents of all slots\n");
+    fprintf(stderr, "\t\tcurrent              Show contents of current slot\n");
+    fprintf(stderr, "\t\tslot <slot #>        load tape from slot <slot #>\n");
+    fprintf(stderr, "\t\tslot current         load tape from current slot\n");
+    fprintf(stderr, "\t\tslot prev            load tape from previous slot\n");
+    fprintf(stderr, "\t\tslot next            load tape from next slot\n");
+    fprintf(stderr, "\t\tslot advance         advance to next slot but do not load\n");
+    fprintf(stderr, "\t\tslot first           load tape from first slot\n");
+    fprintf(stderr, "\t\tslot last            load tape from last slot\n");
+    fprintf(stderr, "\t\tlabel <label>        find and load labeled tape\n");
+    fprintf(stderr, "\t\ttaper                perform taper's scan alg.\n");
+    fprintf(stderr, "\t\tdevice               show current tape device\n");
+    fprintf(stderr, "\t\tupdate               update the label matchingdatabase\n");
+
+    exit(1);
+}
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    char *conffile;
+    char *conf_tapelist;
+    char *argv0 = argv[0];
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    int fd;
+    int have_changer;
+    uid_t uid_me;
+    uid_t uid_dumpuser;
+    char *dumpuser;
+    struct passwd *pw;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amtape");
+    dbopen();
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = ERR_INTERACTIVE;
+
+    if(argc < 3) usage();
+
+    config_name = argv[1];
+
+    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);
+    }
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+    amfree(conf_tapelist);
+
+    uid_me = getuid();
+    uid_dumpuser = uid_me;
+    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);
+       /* NOTREACHED */
+    }
+
+    if((have_changer = changer_init()) == 0) {
+       error("no tpchanger specified in \"%s\"", conffile);
+    } else if (have_changer != 1) {
+       error("changer initialization failed: %s", strerror(errno));
+    }
+
+    /* switch on command name */
+
+    argc -= 2; argv += 2;
+    if(strcmp(argv[0], "reset") == 0) reset_changer(argc, argv);
+    else if(strcmp(argv[0], "clean") == 0) clean_tape(argc, argv);
+    else if(strcmp(argv[0], "eject") == 0) eject_tape(argc, argv);
+    else if(strcmp(argv[0], "slot") == 0) load_slot(argc, argv);
+    else if(strcmp(argv[0], "label") == 0) load_label(argc, argv);
+    else if(strcmp(argv[0], "current") == 0)  show_current(argc, argv);
+    else if(strcmp(argv[0], "show") == 0)  show_slots(argc, argv);
+    else if(strcmp(argv[0], "taper") == 0) taper_scan(argc, argv);
+    else if(strcmp(argv[0], "device") == 0) show_device(argc, argv);
+    else if(strcmp(argv[0], "update") == 0) update_labeldb(argc, argv);
+    else {
+       fprintf(stderr, "%s: unknown command \"%s\"\n", argv0, argv[0]);
+       usage();
+    }
+
+    amfree(changer_resultstr);
+    amfree(conffile);
+    amfree(config_dir);
+
+    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);
+    }
+
+    dbclose();
+    return 0;
+}
+
+/* ---------------------------- */
+
+void reset_changer(argc, argv)
+int argc;
+char **argv;
+{
+    char *slotstr = NULL;
+
+    switch(changer_reset(&slotstr)) {
+    case 0:
+       fprintf(stderr, "%s: changer is reset, slot %s is loaded.\n",
+               get_pname(), slotstr);
+       break;
+    case 1:
+       fprintf(stderr, "%s: changer is reset, but slot %s not loaded: %s\n",
+               get_pname(), slotstr, changer_resultstr);
+       break;
+    default:
+       error("could not reset changer: %s", changer_resultstr);
+    }
+    amfree(slotstr);
+}
+
+
+/* ---------------------------- */
+void clean_tape(argc, argv)
+int argc;
+char **argv;
+{
+    char *devstr = NULL;
+
+    if(changer_clean(&devstr) == 0) {
+       fprintf(stderr, "%s: device %s is clean.\n", get_pname(), devstr);
+    } else {
+       fprintf(stderr, "%s: device %s not clean: %s\n",
+               get_pname(), devstr ? devstr : "??", changer_resultstr);
+    }
+    amfree(devstr);
+}
+
+
+/* ---------------------------- */
+void eject_tape(argc, argv)
+int argc;
+char **argv;
+{
+    char *slotstr = NULL;
+
+    if(changer_eject(&slotstr) == 0) {
+       fprintf(stderr, "%s: slot %s is ejected.\n", get_pname(), slotstr);
+    } else {
+       fprintf(stderr, "%s: slot %s not ejected: %s\n",
+               get_pname(), slotstr ? slotstr : "??", changer_resultstr);
+    }
+    amfree(slotstr);
+}
+
+
+/* ---------------------------- */
+
+void load_slot(argc, argv)
+int argc;
+char **argv;
+{
+    char *slotstr = NULL, *devicename = NULL;
+    char *errstr;
+    int is_advance;
+
+    if(argc != 2)
+       usage();
+
+    is_advance = (strcmp(argv[1], "advance") == 0);
+    if(changer_loadslot(argv[1], &slotstr, &devicename)) {
+       error("could not load slot %s: %s", slotstr, changer_resultstr);
+    }
+    if(! is_advance && (errstr = tape_rewind(devicename)) != NULL) {
+       fprintf(stderr,
+               "%s: could not rewind %s: %s", get_pname(), devicename, errstr);
+       amfree(errstr);
+    }
+
+    fprintf(stderr, "%s: changed to slot %s", get_pname(), slotstr);
+    if(! is_advance) {
+       fprintf(stderr, " on %s", devicename);
+    }
+    fputc('\n', stderr);
+    amfree(slotstr);
+    amfree(devicename);
+}
+
+
+/* ---------------------------- */
+
+int nslots, backwards, found, got_match, tapedays;
+char *datestamp;
+char *label = NULL, *first_match_label = NULL, *first_match = NULL;
+char *searchlabel, *labelstr;
+tape_t *tp;
+
+int scan_init(rc, ns, bk)
+int rc, ns, bk;
+{
+    if(rc)
+       error("could not get changer info: %s", changer_resultstr);
+
+    nslots = ns;
+    backwards = bk;
+
+    return 0;
+}
+
+int loadlabel_slot(rc, slotstr, device)
+int rc;
+char *slotstr;
+char *device;
+{
+    char *errstr;
+
+    if(rc > 1)
+       error("could not load slot %s: %s", slotstr, changer_resultstr);
+    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)
+       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);
+       if(strcmp(label, FAKE_LABEL) != 0
+          && strcmp(label, searchlabel) != 0)
+           fprintf(stderr, " (wrong tape)\n");
+       else {
+           fprintf(stderr, " (exact label match)\n");
+           if((errstr = tape_rewind(device)) != NULL) {
+               fprintf(stderr,
+                       "%s: could not rewind %s: %s",
+                       get_pname(), device, errstr);
+               amfree(errstr);
+           }
+           found = 1;
+           amfree(datestamp);
+           amfree(label);
+           return 1;
+       }
+    }
+    amfree(datestamp);
+    amfree(label);
+    return 0;
+}
+
+void load_label(argc, argv)
+int argc;
+char **argv;
+{
+    if(argc != 2)
+       usage();
+
+    searchlabel = argv[1];
+
+    fprintf(stderr, "%s: scanning for tape with label %s\n",
+           get_pname(), searchlabel);
+
+    found = 0;
+
+    changer_find(scan_init, loadlabel_slot, searchlabel);
+
+    if(found)
+       fprintf(stderr, "%s: label %s is now loaded.\n",
+               get_pname(), searchlabel);
+    else
+       fprintf(stderr, "%s: could not find label %s in tape rack.\n",
+               get_pname(), searchlabel);
+}
+
+
+/* ---------------------------- */
+
+int show_init(rc, ns, bk)
+int rc, ns, bk;
+{
+    if(rc)
+       error("could not get changer info: %s", changer_resultstr);
+
+    nslots = ns;
+    backwards = bk;
+    return 0;
+}
+
+int show_init_all(rc, ns, bk)
+int rc, ns, bk;
+{
+    int ret = show_init(rc, ns, bk);
+    fprintf(stderr, "%s: scanning all %d slots in tape-changer rack:\n",
+           get_pname(), nslots);
+    return ret;
+}
+
+int show_init_current(rc, ns, bk)
+int rc, ns, bk;
+{
+    int ret = show_init(rc, ns, bk);
+    fprintf(stderr, "%s: scanning current slot in tape-changer rack:\n",
+           get_pname());
+    return ret;
+}
+
+int update_one_slot(rc, slotstr, device)
+int rc;
+char *slotstr, *device;
+{
+    char *errstr;
+
+    if(rc > 1)
+       error("could not load slot %s: %s", slotstr, changer_resultstr);
+    else if(rc == 1)
+       fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
+    else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
+       fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
+    else {
+       fprintf(stderr, "slot %s: date %-8s label %s\n",
+               slotstr, datestamp, label);
+       changer_label(slotstr,label);
+    }
+    amfree(datestamp);
+    amfree(label);
+    return 0;
+}
+
+int show_slot(rc, slotstr, device)
+int rc;
+char *slotstr, *device;
+{
+    char *errstr;
+
+    if(rc > 1)
+       error("could not load slot %s: %s", slotstr, changer_resultstr);
+    else if(rc == 1)
+       fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
+    else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
+       fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
+    else {
+       fprintf(stderr, "slot %s: date %-8s label %s\n",
+               slotstr, datestamp, label);
+    }
+    amfree(datestamp);
+    amfree(label);
+    return 0;
+}
+
+void show_current(argc, argv)
+int argc;
+char **argv;
+{
+    if(argc != 1)
+       usage();
+
+    changer_current(show_init_current, show_slot);
+}
+
+void update_labeldb(argc, argv)
+int argc;
+char **argv;
+{
+    if(argc != 1)
+       usage();
+
+    changer_scan(show_init_all, update_one_slot);
+}
+
+void show_slots(argc, argv)
+int argc;
+char **argv;
+{
+    if(argc != 1)
+       usage();
+
+    changer_scan(show_init_all, show_slot);
+}
+
+
+/* ---------------------------- */
+
+int taperscan_slot(rc, slotstr, device)
+int rc;
+char *slotstr;
+char *device;
+{
+    char *errstr;
+
+    if(rc == 2)
+       error("could not load slot %s: %s", slotstr, changer_resultstr);
+    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) {
+           fprintf(stderr, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
+       } else {
+           /* got an amanda tape */
+           fprintf(stderr, "%s: slot %s: date %-8s label %s",
+                   get_pname(), slotstr, datestamp, label);
+           if(searchlabel != NULL
+              && (strcmp(label, FAKE_LABEL) == 0
+                  || strcmp(label, searchlabel) == 0)) {
+               /* it's the one we are looking for, stop here */
+               fprintf(stderr, " (exact label match)\n");
+               found = 1;
+               amfree(datestamp);
+               amfree(label);
+               return 1;
+           }
+           else if(!match(labelstr, label))
+               fprintf(stderr, " (no match)\n");
+           else {
+               /* not an exact label match, but a labelstr match */
+               /* check against tape list */
+               tp = lookup_tapelabel(label);
+               if(tp == NULL)
+                   fprintf(stderr, " (not in tapelist)\n");
+               else if(!reusable_tape(tp))
+                   fprintf(stderr, " (active tape)\n");
+               else if(got_match == 0 && tp->datestamp == 0) {
+                   got_match = 1;
+                   first_match = newstralloc(first_match, slotstr);
+                   first_match_label = newstralloc(first_match_label, label);
+                   fprintf(stderr, " (new tape)\n");
+                   found = 3;
+                   amfree(datestamp);
+                   amfree(label);
+                   return 1;
+               }
+               else if(got_match)
+                   fprintf(stderr, " (labelstr match)\n");
+               else {
+                   got_match = 1;
+                   first_match = newstralloc(first_match, slotstr);
+                   first_match_label = newstralloc(first_match_label, label);
+                   fprintf(stderr, " (first labelstr match)\n");
+                   if(!backwards || !searchlabel) {
+                       found = 2;
+                       amfree(datestamp);
+                       amfree(label);
+                       return 1;
+                   }
+               }
+           }
+       }
+    }
+    amfree(datestamp);
+    amfree(label);
+    return 0;
+}
+
+void taper_scan(argc, argv)
+int argc;
+char **argv;
+{
+    char *slotstr = NULL, *device = NULL;
+
+    if((tp = lookup_last_reusable_tape(0)) == NULL)
+       searchlabel = NULL;
+    else
+       searchlabel = stralloc(tp->label);
+
+    tapedays   = getconf_int(CNF_TAPECYCLE);
+    labelstr   = getconf_str(CNF_LABELSTR);
+    found = 0;
+    got_match = 0;
+
+    fprintf(stderr, "%s: scanning for ", get_pname());
+    if(searchlabel) fprintf(stderr, "tape label %s or ", searchlabel);
+    fprintf(stderr, "a new tape.\n");
+
+    if (searchlabel != NULL)
+      changer_find(scan_init, taperscan_slot, searchlabel);
+    else
+      changer_scan(scan_init, taperscan_slot);
+
+    if(found == 3) {
+       fprintf(stderr, "%s: settling for new tape\n", get_pname());
+       searchlabel = newstralloc(searchlabel, first_match_label);
+    }
+    else if(found == 2) {
+       fprintf(stderr, "%s: %s: settling for first labelstr match\n",
+               get_pname(),
+               searchlabel? "gravity stacker": "looking only for new tape");
+       searchlabel = newstralloc(searchlabel, first_match_label);
+    }
+    else if(!found && got_match) {
+       fprintf(stderr,
+               "%s: %s not found, going back to first labelstr match %s\n",
+               get_pname(), searchlabel, first_match_label);
+       searchlabel = newstralloc(searchlabel, first_match_label);
+       if(changer_loadslot(first_match, &slotstr, &device) == 0) {
+           found = 1;
+       } else {
+           fprintf(stderr, "%s: could not load labelstr match in slot %s: %s\n",
+                   get_pname(), first_match, changer_resultstr);
+       }
+       amfree(device);
+       amfree(slotstr);
+    }
+    else if(!found) {
+       fprintf(stderr, "%s: could not find ", get_pname());
+       if(searchlabel) fprintf(stderr, "tape %s or ", searchlabel);
+       fprintf(stderr, "a new tape in the tape rack.\n");
+    }
+
+    if(found)
+       fprintf(stderr, "%s: label %s is now loaded.\n",
+               get_pname(), searchlabel);
+
+    amfree(searchlabel);
+    amfree(first_match);
+    amfree(first_match_label);
+}
+
+/* ---------------------------- */
+
+void show_device(argc, argv)
+int argc;
+char **argv;
+{
+    char *slot = NULL, *device = NULL;
+
+    if(changer_loadslot("current", &slot, &device))
+       error("Could not load current slot.\n");
+
+    printf("%s\n", device);
+    amfree(slot);
+    amfree(device);
+}
diff --git a/server-src/amtoc.pl.in b/server-src/amtoc.pl.in
new file mode 100644 (file)
index 0000000..0e6a8d7
--- /dev/null
@@ -0,0 +1,241 @@
+#!@PERL@ -w
+
+# create a TOC (Table Of Content) file for an amanda dump
+
+# Author: Nicolas.Mayencourt@cui.unige.ch
+
+# release 3.1.4
+
+# HISTORY
+# 1.0 19??-??-?? nicolas@cui.unige.ch
+#      don't remember :-)
+# 2.0 1996-??-?? nicolas@cui.unige.ch
+#      amanda 2.2.6 support
+# 3.0 1999-02-17 Nicolas.Mayencourt@cui.unige.ch
+#      major rewrite, incompatible with release 2.0, amanda 2.4 support
+# 3.0.1 1999-02-17 oliva@dcc.unicamp.br
+#      minor fixes for multi-tape runs
+# 3.0.2 1999-02-28 martineau@IRO.UMontreal.CA
+#      output the datestamp of each dump
+# 3.0.3 1999-09-01 jrj@purdue.edu
+#      allow multiple -s entries
+# 3.0.4 1999-09-15 jrj@purdue.edu
+#      handle an image failing on one tape...
+# 3.1.0 1999-10-06 Nicolas.Mayencourt@cui.unige.ch
+#      add new options (-i -t)
+# 3.1.1 1999-10-08 Nicolas.Mayencourt@cui.unige.ch
+#      print original size, instead of size-on-tape
+# 3.1.2 1999-10-11 Nicolas.Mayencourt@cui.unige.ch
+#      really print original size, instead of size-on-tape
+# 3.1.3 Nicolas.Mayencourt@cui.unige.ch
+#      correct a bug for total report
+# 3.1.4 2000-01-14 dhw@whistle.com
+#      Add a flag (-w) for vertical whitespace
+
+
+#--------------------------------------------------------
+sub pr($$$$$$) { 
+# you can update these proc if you want another formating
+# format: filenumber  host:part  date  level  size
+# If you use tabular option, modifie the format at the end of the code
+  if (defined($tabular)) {
+       $fnbr=$_[0];
+       $hstprt=$_[1] . ":" . $_[2];
+       $dt=$_[3];
+       $lvl=$_[4];
+       $sz=$_[5];
+    write($OF);
+  } else {
+    print $OF "$_[0]  $_[1]:$_[2]  $_[3]  $_[4]  $_[5]\n";
+  }
+}
+#--------------------------------------------------------
+
+
+
+#--------------------------------------------------------
+sub tfn($) {
+  # calculate tocfilename
+  $_ = $_[0];
+  foreach $s (@subs) {
+    eval $s;
+  }
+  return $dir . $_ ;
+}
+#--------------------------------------------------------
+
+
+#--------------------------------------------------------
+sub usage($) {
+  print STDERR "@_\n\n";
+  print STDERR "usage: amtoc [-a] [-i] [-t] [-f file] [-s subs] [-w] [--] logfile\n";
+  print STDERR "         -a      : file output to `label`.toc\n";
+  print STDERR "         -i      : Start TOC with a small help message\n";
+  print STDERR "         -t      : tabular output\n";
+  print STDERR "         -f file : output to file\n";
+  print STDERR "         -s subs : output file name evaluated to `eval \$subs`\n";
+  print STDERR "         -w      : add vertical whitespace after each tape\n";
+  print STDERR "         --      : last option\n";
+  print STDERR "         logfile : input file ('-' for stdin)\n";
+  exit;
+}
+#--------------------------------------------------------
+
+#--------------------------------------------------------
+sub init() {
+  &usage("amtoc required at least 'logfile' parameter.") if ($#ARGV==-1) ;
+
+  @subs = ();
+  for ($i=0;$i<=$#ARGV;$i++) {
+    if ($ARGV[$i] eq '-a') {
+        push (@subs, "s/\$/.toc/");
+      }
+    elsif ($ARGV[$i] eq '-i') {
+        $info=1;
+      }
+    elsif ($ARGV[$i] eq '-t') {
+        $tabular=1;
+      }
+    elsif ($ARGV[$i] eq '-f') {
+        $i++;
+        &usage("'-f' option require 'file' parameter.")  if ($i > $#ARGV);
+        $tocfilename=$ARGV[$i];
+      }
+    elsif ($ARGV[$i] eq '-s') {
+        $i++;
+        &usage("'-s' option require 'subs' parameter.")  if ($i > $#ARGV);
+        push (@subs, $ARGV[$i]);
+      }
+    elsif ($ARGV[$i] eq '-w') {
+        $vwspace=1;
+      }
+    elsif ($ARGV[$i] eq '--') {
+      # no more options: next arg == logfile
+        $i++;
+        &usage("amtoc required at least 'logfile' parameter.") if ($i > $#ARGV);
+        $logfile=$ARGV[$i];
+        &usage("too many parameters.") unless ($i == $#ARGV);
+      }
+    else {
+        $logfile=$ARGV[$i];
+        &usage("too many parameters.") unless ($i == $#ARGV);
+      }
+  }
+  &usage("amtoc required at least 'logfile' parameter.") unless ($logfile);
+}
+
+#--------------------------------------------------------
+
+&init;
+
+$dir=$logfile;
+$dir =~ s/[^\/]*$//;
+
+
+if ($logfile eq '-') {$IF=STDIN} else 
+  {die ("Cannot open logfile $logfile") unless open (IF,"$logfile");$IF=IF;}
+
+$filenumber=0;
+$tot_or_size=0;
+
+while ( <$IF> ) {
+  $line = $_;
+  if ( /^FAIL dumper (\S+) (\S+)/ ) {
+    next;
+  }
+  if ( /^SUCCESS dumper (\S+) (\S+)/ ) {
+    $host = $1;
+    $part = $2;
+    $line =~ /orig-kb (\d+)/;
+    $osize{$host}{$part} = $1;
+    $tot_or_size += $osize{$host}{$part};
+    $fail{$host}{$part} = 0;
+    next;
+  }
+  if ( /^START amflush/ ) {
+    $flash_mode = 1;
+    next;
+  }
+  if ( ! /^([A-Z]+) taper (\S+) (\S+) (\S+) (\S+)/) { next;}
+  # $_ = $1;
+  $host = $2;
+  $part = $3;
+  $date = $4;
+  $level = $5;
+  switch: {
+    /START taper/ && do {
+      $tocfilename=&tfn($level) if ($#subs >= 0);
+      if (!$tocfilename || ($tocfilename eq '-')) {$OF=STDOUT;}
+      else {
+          die ("Cannot open tocfile $tocfilename") unless open(OF,">$tocfilename");
+          $OF=OF;
+        }
+
+       print $OF "\f" if ($vwspace && $filenumber);
+       if (defined($info)) {
+         print $OF "AMANDA: To restore:\n";
+         print $OF "    position tape at start of file and run:\n";
+         print $OF "        dd if=<tape> bs=32k skip=1 [ | zcat ] | restore -...f\n";
+         print $OF "    or run: amrestore -p <tape> [host [partition]] | restore -...f\n";
+         print $OF "\n";
+       }
+
+
+
+      $filenumber=0;
+      &pr("#","Server","/partition","date", "level","size[Kb]");
+      &pr("$filenumber","$level","","$part","-","-");
+      last switch; };
+    /SUCCESS taper/ && do {
+      $line =~ / kb (\d+) /;
+      if ( $fail{$host}{$part} ) {
+        &pr("$filenumber","${host}","${part}","${date}","${level}","FAIL");
+      } else {
+       if (defined($flash_mode)) {
+          &pr("$filenumber","${host}","${part}","${date}","${level}","$1");
+       } else {
+         if (defined($osize{$host}{$part})) {
+            &pr("$filenumber","${host}","${part}","${date}","${level}","$osize{$host}{$part}");
+         } else {
+               # this case should never happend: 
+            &pr("$filenumber","${host}","${part}","${date}","${level}","*$1");
+           $strange=1;
+         }
+       }
+      }
+      last switch;};
+    /INFO taper retrying/ && do {
+      --$filenumber;
+      last switch; };
+    /INFO taper tape .* \[OK\]/ && do {
+      $line =~ / kb (\d+) /;
+      $size = $1;
+      $line =~ / fm (\d+) /;
+      print "\n\n" if ($vwspace);
+      &pr("$1","total","on_tape","-","-","$size");
+      if (defined($flash_mode)) {
+       &pr("$1","total","origin","-","not","available");
+      } else {
+       &pr("$1","total","origin","-","-","$tot_or_size");
+      }
+      if (defined($strange)) {
+       &pr("*","size","on_tape","-","-","-");
+      }
+      last switch; };
+    /FAIL taper/ && do { next; };
+  }
+  $filenumber += 1;
+}
+close $IF;
+close OF;
+
+
+format OF =
+@>>  @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<< @>> @>>>>>>>>
+$fnbr,$hstprt,$dt,$lvl,$sz
+.
+
+format STDOUT =
+@>>  @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<< @>> @>>>>>>>>
+$fnbr,$hstprt,$dt,$lvl,$sz
+.
diff --git a/server-src/amtrmidx.c b/server-src/amtrmidx.c
new file mode 100644 (file)
index 0000000..6613be4
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * 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: amtrmidx.c,v 1.21.4.1.4.2.2.6 2004/02/12 18:28:42 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
+ * dump.
+ */
+
+#include "amanda.h"
+#include "arglist.h"
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#include "conffile.h"
+#include "diskfile.h"
+#include "tapefile.h"
+#include "find.h"
+#include "version.h"
+
+static int sort_by_name_reversed(a, b)
+const void *a;
+const void *b;
+{
+    char **ap = (char **) a;
+    char **bp = (char **) b;
+
+    return -1 * strcmp(*ap, *bp);
+}
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    disk_t *diskp;
+    disklist_t *diskl;
+    int i;
+    char *conffile;
+    char *conf_diskfile;
+    char *conf_tapelist;
+    char *conf_indexdir;
+    int fd;
+    find_result_t *output_find;
+    time_t tmp_time;
+    int amtrmidx_debug = 0;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amtrmidx");
+
+    dbopen();
+    dbprintf(("%s: version %s\n", argv[0], version()));
+
+    if (argc > 1 && strcmp(argv[1], "-t") == 0) {
+       amtrmidx_debug = 1;
+       argc--;
+       argv++;
+    }
+
+    if (argc < 2) {
+       fprintf(stderr, "Usage: %s [-t] <config>\n", argv[0]);
+       return 1;
+    }
+
+    config_name = argv[1];
+
+    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);
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if(*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((diskl = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist \"%s\".", conf_diskfile);
+    }
+    amfree(conf_diskfile);
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+    amfree(conf_tapelist);
+
+    output_find = find_dump(1, diskl);
+
+    conf_indexdir = getconf_str(CNF_INDEXDIR);
+    if(*conf_indexdir == '/') {
+       conf_indexdir = stralloc(conf_indexdir);
+    } else {
+       conf_indexdir = stralloc2(config_dir, conf_indexdir);
+    }
+
+    /* now go through the list of disks and find which have indexes */
+    time(&tmp_time);
+    tmp_time -= 7*24*60*60;                    /* back one week */
+    for (diskp = diskl->head; diskp != NULL; diskp = diskp->next) {
+       if (diskp->index) {
+           char *indexdir;
+           DIR *d;
+           struct dirent *f;
+           char **names;
+           int name_length;
+           int name_count;
+           char *host;
+           char *disk;
+
+           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);
+           indexdir = vstralloc (conf_indexdir, "/",
+                                 host, "/",
+                                 disk, "/",
+                                 NULL);
+           amfree(host);
+           amfree(disk);
+           if((d = opendir(indexdir)) == NULL) {
+               dbprintf(("could not open index directory \"%s\"\n", indexdir));
+               amfree(indexdir);
+               continue;
+           }
+           name_length = 100;
+           names = (char **)alloc(name_length * sizeof(char *));
+           name_count = 0;
+           while ((f = readdir(d)) != NULL) {
+               int l;
+
+               if(is_dot_or_dotdot(f->d_name)) {
+                   continue;
+               }
+               for(i = 0; i < sizeof("YYYYMMDD")-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]))) {
+                   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) {
+                   struct stat sbuf;
+                   char *path;
+
+                   path = stralloc2(indexdir, f->d_name);
+                   if(lstat(path, &sbuf) != -1
+                       && (sbuf.st_mode & S_IFMT) == S_IFREG
+                       && sbuf.st_mtime < tmp_time) {
+                       dbprintf(("rm %s\n", path));
+                       if(amtrmidx_debug == 0 && unlink(path) == -1) {
+                           dbprintf(("Error removing \"%s\": %s\n",
+                                     path, strerror(errno)));
+                       }
+                   }
+                   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;
+                   amfree(names);
+                   names = new_names;
+               }
+               names[name_count++] = stralloc(f->d_name);
+           }
+           closedir(d);
+           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;
+                   path = stralloc2(indexdir, names[i]);
+                   dbprintf(("rm %s\n", path));
+                   if(amtrmidx_debug == 0 && unlink(path) == -1) {
+                       dbprintf(("Error removing \"%s\": %s\n",
+                                 path, strerror(errno)));
+                   }
+                   amfree(path);
+               }
+               amfree(names[i]);
+           }
+           amfree(names);
+           amfree(indexdir);
+       }
+    }
+
+    amfree(conf_indexdir);
+    amfree(config_dir);
+    free_find_result(&output_find);
+
+    dbclose();
+
+    return 0;
+}
diff --git a/server-src/amtrmlog.c b/server-src/amtrmlog.c
new file mode 100644 (file)
index 0000000..065547d
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * 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: amtrmlog.c,v 1.1.2.3.4.1.2.2 2003/01/01 23:28:53 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
+ * dump.
+ */
+
+#include "amanda.h"
+#include "arglist.h"
+#ifdef HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#include "conffile.h"
+#include "diskfile.h"
+#include "tapefile.h"
+#include "find.h"
+#include "version.h"
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    disklist_t *diskl;
+    int no_keep;                       /* files per system to keep */
+    int fd;
+    char **output_find_log;
+    DIR *dir;
+    struct dirent *adir;
+    char **name;
+    int useful;
+    char *olddir;
+    char *oldfile = NULL, *newfile = NULL;
+    time_t today, date_keep;
+    char *logname = NULL;
+    struct stat stat_log;
+    struct stat stat_old;
+    char *conffile;
+    char *conf_diskfile;
+    char *conf_tapelist;
+    char *conf_logdir;
+    int amtrmidx_debug = 0;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    safe_cd();
+
+    set_pname("amtrmlog");
+
+    if (argc > 1 && strcmp(argv[1], "-t") == 0) {
+       amtrmidx_debug = 1;
+       argc--;
+       argv++;
+    }
+
+    if (argc != 2) {
+       fprintf(stderr, "Usage: %s [-t] <config>\n", argv[0]);
+       return 1;
+    }
+
+    dbopen();
+    dbprintf(("%s: version %s\n", argv[0], version()));
+
+    config_name = argv[1];
+
+    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);
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((diskl = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist %s", conf_diskfile);
+    }
+    amfree(conf_diskfile);
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+    amfree(conf_tapelist);
+
+    today = time((time_t *)NULL);
+    date_keep = today - (getconf_int(CNF_DUMPCYCLE)*86400);
+
+    output_find_log = find_log(NULL,0,NULL);
+
+    /* determine how many log to keep */
+    no_keep = getconf_int(CNF_TAPECYCLE) * 2;
+    dbprintf(("Keeping %d log file%s\n", no_keep, (no_keep == 1) ? "" : "s"));
+
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+       conf_logdir = stralloc(conf_logdir);
+    } else {
+       conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    olddir = vstralloc(conf_logdir, "/oldlog", NULL);
+    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) {
+       error("could not create %s: %s", olddir, strerror(errno));
+    }
+
+    if (stat(olddir,&stat_old) == -1) {
+       error("can't stat oldlog directory \"%s\": %s", olddir, strerror(errno));
+    }
+
+    if (!S_ISDIR(stat_old.st_mode)) {
+       error("Oldlog directory \"%s\" is not a directory", olddir);
+    }
+    if ((dir = opendir(conf_logdir)) == NULL) {
+       error("could not open log directory \"%s\": %s", conf_logdir, strerror(errno));
+    }
+    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) {
+                   useful = 1;
+               }
+           }
+           logname = newvstralloc(logname,
+                                  conf_logdir, "/", adir->d_name, NULL);
+           if(stat(logname, &stat_log) == 0) {
+               if(stat_log.st_mtime > date_keep) {
+                   useful = 1;
+               }
+           }
+           if(! useful) {
+               oldfile = newvstralloc(oldfile,
+                                      conf_logdir, "/", adir->d_name, NULL);
+               newfile = newvstralloc(newfile,
+                                      olddir, "/", adir->d_name, NULL);
+               if(rename(oldfile, newfile) != 0) {
+                   error("could not rename \"%s\" to \"%s\": %s",
+                         oldfile, newfile, strerror(errno));
+               }
+           }
+       }
+    }
+    closedir(dir);
+    for (name = output_find_log; *name != NULL; name++) {
+       amfree(*name);
+    }
+    amfree(output_find_log);
+    amfree(logname);
+    amfree(oldfile);
+    amfree(newfile);
+    amfree(olddir);
+    amfree(config_dir);
+    amfree(conf_logdir);
+
+    dbclose();
+
+    return 0;
+}
diff --git a/server-src/amverify.sh.in b/server-src/amverify.sh.in
new file mode 100644 (file)
index 0000000..6608ac9
--- /dev/null
@@ -0,0 +1,461 @@
+#! /bin/sh
+#
+#      $Id: amverify.sh.in,v 1.7.2.13.4.5.2.6 2003/10/24 13:44:49 martinea Exp $
+#
+# (C) 1996 by ICEM Systems GmbH
+# Author: Axel Zinser (fifi@icem.de)
+#
+# amverify: check amanda tapes and report errors
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if [ "$USE_VERSION_SUFFIXES" = "yes" ]; then
+       SUF="-@VERSION@"
+else
+       SUF=
+fi
+
+# If the shell/system echo support \r and \c, use them to write some
+# status messages over the top of each other as things progress, otherwise
+# use a normal echo and let them go on new lines.  Define $Echoe to be
+# an echo that goes to stderr.  In the code, $Echoe is used and it may
+# be either echoe or echone, the latter being code that knows about echon.
+
+t=`echo "abc\r\c" | wc -c`
+if [ $t -eq 4 ]; then
+       Echon=echon
+else
+       Echon=echo
+fi
+Echoe=echoe
+elen=0
+echoe() {
+       echo "$@" >&2
+       Echoe=echoe
+}
+echon() {
+        newelen=`expr "$1" : '.*'`
+       blanks=
+        while [ $newelen -lt $elen ]; do
+               blanks="$blanks "
+                elen=`expr $elen - 1`
+        done
+        echo "$1""$blanks\r\c"
+        elen=$newelen
+       Echoe=echone
+}
+echone() {
+       echon
+       echoe "$@"
+       Echoe=echoe
+}
+
+report() {
+       $Echoe "$@"
+       echo "$@" >> $REPORT
+}
+
+getparm() {
+       $AMGETCONF $CONFIG $1 2>/dev/null | grep -v BUGGY
+}
+
+sendreport() {
+       if [ -f $REPORT -a X"$REPORTTO" != X"" ]; then
+               (
+               echo "Tapes: $TAPELIST"
+               if [ -s $DEFECTS ]; then
+                       echo "Errors found: "
+                       cat $DEFECTS
+               else
+                       echo "No errors found!"
+               fi
+               echo
+
+               [ -s $REPORT ] \
+                       && cat $REPORT
+               ) | $MAIL -s "$ORG AMANDA VERIFY REPORT FOR$TAPELIST" $REPORTTO
+       fi
+}
+
+###
+# This function is called to process one dump image.  Standard input is
+# the dump image.  We parse the header and decide if it is a GNU tar
+# dump or a system dump.  Then we do a catalog operation to /dev/null
+# and finally a "cat" to /dev/null to soak up whatever data is still in
+# the pipeline.
+#
+# In the case of a system restore catalogue, this does not fully check
+# the integrity of the dump image because system restore programs stop
+# as soon as they are done with the directories, which are all at the
+# beginning.  But the trailing cat will at least make sure the whole
+# image is readable.
+###
+
+doonefile() {
+
+       ###
+       # The goal here is to collect the first 32 KBytes and save the
+       # first line.  But the pipe size coming in to us from amrestore
+       # is highly system dependent and "dd" does not do reblocking.
+       # So we pick a block size that is likely to always be available in
+       # the pipe and a count to take it up to 32 KBytes.  Worst case,
+       # this could be changed to "bs=1 count=32k".  We also have to
+       # soak up the rest of the output after the "head" so an EPIPE
+       # does not go back and terminate the "dd" early.
+       ###
+
+       HEADER=`$DD bs=512 count=64 | ( sed 1q ; cat > /dev/null )`
+       CMD=
+       result=1
+       if [ X"$HEADER" = X"" ]; then
+               echo "** No header" > $TEMP/errors
+       else
+               set X $HEADER
+               shift
+               shift 9
+               if [ X"$1" = X"program" -a X"$2" != X"" ]; then
+                       if [ X"$TAR" != X"" \
+                            -a \( X"`basename $2`" = X"`basename $TAR`" \
+                                  -o X"`basename $2`" = X"gtar" \
+                                  -o X"`basename $2`" = X"gnutar" \
+                                  -o X"`basename $2`" = X"tar" \) ]; then
+                               CMD=$TAR
+                               ARGS="tf -"
+                       elif [ X"$TAR" != X"" \
+                              -a X"$SAMBA_CLIENT" != X"" \
+                              -a X"$2" = X"$SAMBA_CLIENT" ]; then
+                               CMD=$TAR
+                               ARGS="tf -"
+                       elif [ X"$DUMP" != X"" -a X"$2" = X"$DUMP" ]; then
+                               CMD=$RESTORE
+                               if [ $IS_AIX -eq 1 ]; then
+                                       ARGS=-tB
+                               else
+                                       ARGS="tbf 2 -"
+                               fi
+                       elif [ X"$VDUMP" != X"" -a X"$2" = X"$VDUMP" ]; then
+                               CMD=$VRESTORE
+                               ARGS="tf -"
+                       elif [ X"$VXDUMP" != X"" -a X"$2" = X"$VXDUMP" ]; then
+                               CMD=$VXRESTORE
+                               ARGS="tbf 2 -"
+                       elif [ X"$XFSDUMP" != X"" -a X"$2" = X"$XFSDUMP" ]; then
+                               CMD=$XFSRESTORE
+                               ARGS="-t -v silent -"
+                       else
+                               echo "** Cannot do $2 dumps" > $TEMP/errors
+                               result=999      # flag as not really an error
+                       fi
+               else
+                       echo "** Cannot find dump type" > $TEMP/errors
+               fi
+       fi
+       if [ X"$CMD" != X"" ]; then
+               if [ -x $CMD ]; then
+                       $CMD $ARGS > /dev/null 2> $TEMP/errors
+                       result=$?
+               else
+                       echo "** Cannot execute $CMD" > $TEMP/errors
+               fi
+       fi
+       cat >/dev/null                          # soak up the rest of the image
+       echo $result
+}
+
+#
+# some paths
+#
+#      CONFIG_DIR      directory in which the config file resides
+#      AMRESTORE       full path name of amrestore
+#      AMGETCONF       full path name of amgetconf
+#      AMTAPE          full path name of amtape
+#      TAR             ditto for GNU-tar
+#      SAMBA_CLIENT    ditto for smbclient
+#      DUMP            ditto for the system dump program
+#      RESTORE         ditto for the system restore program
+#      VDUMP           ditto for the system dump program
+#      VRESTORE        ditto for the system restore program
+#      VXDUMP          ditto for the system dump program
+#      VXRESTORE       ditto for the system restore program
+#      XFSDUMP         ditto for the system dump program
+#      XFSRESTORE      ditto for the system restore program
+#      DD              ditto for dd
+#      MT              ditto for mt
+#      MTF             flag given to MT to specify tape device: -f or -t
+#      MAIL            mail program
+#      IS_AIX          true if this is an AIX system
+
+CONFIG_DIR=@CONFIG_DIR@
+libexecdir=$libexecdir
+sbindir=$sbindir
+AMRESTORE=$sbindir/amrestore$SUF
+AMGETCONF=$sbindir/amgetconf$SUF
+AMTAPE=$sbindir/amtape$SUF
+TAR=@GNUTAR@
+SAMBA_CLIENT=@SAMBA_CLIENT@
+DUMP=@DUMP@
+RESTORE=@RESTORE@
+VDUMP=@VDUMP@
+VRESTORE=@VRESTORE@
+VXDUMP=@VXDUMP@
+VXRESTORE=@VXRESTORE@
+XFSDUMP=@XFSDUMP@
+XFSRESTORE=@XFSRESTORE@
+if [ -x $sbindir/ammt$SUF ]; then
+       MT=$sbindir/ammt$SUF
+       MTF=-f
+elif [ -x "@MT@" ]; then
+       MT=@MT@
+       MTF=@MT_FILE_FLAG@
+else
+       $Echoe "amverify$SUF mt program not found"
+       exit 1
+fi
+if [ -x $sbindir/amdd$SUF ]; then
+       DD=$sbindir/amdd$SUF
+elif [ -x "@DD@" ]; then
+       DD=@DD@
+else
+       $Echoe "amverify$SUF dd program not found"
+       exit 1
+fi
+MAIL=@MAILER@
+if [ X"`/bin/uname -s 2>/dev/null`" = X"AIX" ]; then
+       IS_AIX=1
+
+       # The AIX "mt stat" function does not really do anything w.r.t.
+       # checking the drive for ready, and in fact, will fail under
+       # some conditions (e.g. if the tape "file" is a symlink to the
+       # real device).  We let the rewind do the equivalent since all
+       # we use this for is to wait for device ready.
+
+       DEVICE_READY=:
+else
+       IS_AIX=0
+       DEVICE_READY='$MT $MTF $DEVICE stat'
+fi
+
+#
+# config file
+#
+SLOT=0
+CONFIG=$1
+[ X"$CONFIG" = X"" ] \
+       && $Echoe "usage: amverify$SUF <config> [slot [ runtapes ] ]" \
+       && exit 1
+
+AMCONFIG=$CONFIG_DIR/$CONFIG/amanda.conf
+[ ! -f $AMCONFIG ] \
+       && $Echoe "Cannot find config file $AMCONFIG" \
+       && exit 1
+
+TPCHANGER=`getparm tpchanger`
+if [ X"$TPCHANGER" = X"" ]; then
+       $Echoe "No tape changer..."
+       DEVICE=`getparm tapedev`
+       [ X"$DEVICE" = X"" ] \
+               && $Echoe "No tape device..." \
+               && exit 1
+       $Echoe "Tape device is $DEVICE..."
+       SLOTS=1
+else
+       CHANGER_SLOT=${2:-current}
+       $Echoe "Tape changer is $TPCHANGER..."
+       SLOTS=${3:-`getparm runtapes`}
+       [ X"$SLOTS" = X"" ] && SLOTS=1
+       if [ $SLOTS -eq 1 ]; then
+               p=""
+       else
+               p=s
+       fi
+       $Echoe "$SLOTS slot${p}..."
+       MAXRETRIES=2
+fi
+
+#
+# check the accessability
+#
+[ X"$TAR" != X"" -a ! -x "$TAR" ] \
+       && $Echoe "GNU tar not found: $TAR"
+[ X"$DUMP" != X"" -a \( X"$RESTORE" = X"" -o ! -x "$RESTORE" \) ] \
+       && $Echoe "System restore program not found: $RESTORE"
+[ X"$VDUMP" != X"" -a \( X"$VRESTORE" = X"" -o ! -x "$VRESTORE" \) ] \
+       && $Echoe "System restore program not found: $VRESTORE"
+[ X"$VXDUMP" != X"" -a \( X"$VXRESTORE" = X"" -o ! -x "$VXRESTORE" \) ] \
+       && $Echoe "System restore program not found: $VXRESTORE"
+[ X"$XFSDUMP" != X"" -a \( X"$XFSRESTORE" = X"" -o ! -x "$XFSRESTORE" \) ] \
+       && $Echoe "System restore program not found: $XFSRESTORE"
+[ ! -x $AMRESTORE ] \
+       && $Echoe "amrestore not found: $AMRESTORE" \
+       && exit 1
+
+REPORTTO=`getparm mailto`
+if [ X"$REPORTTO" = X"" ]; then
+       $Echoe "No notification by mail!"
+else
+       $Echoe "Verify summary to $REPORTTO"
+fi
+
+ORG=`getparm org`
+if [ X"$ORG" = X"" ]; then
+       $Echoe "No org in amanda.conf -- using $CONFIG"
+       ORG=$CONFIG
+fi
+
+#
+# ok, let's do it
+#
+#      TEMP            directory for temporary tar archives and stderr
+#      DEFECTS         defect list
+#      REPORT          report for mail
+
+if [ ! -d @AMANDA_TMPDIR@ ]; then
+  $Echoe "amverify: directory @AMANDA_TMPDIR@ does not exist."
+  exit 1
+fi
+
+cd @AMANDA_TMPDIR@ || exit 1
+
+TEMP=@AMANDA_TMPDIR@/amverify.$$
+trap 'rm -fr $TEMP' 0
+if ( umask 077 ; mkdir $TEMP ) ; then
+       :
+else
+       $Echoe "Cannot create $TEMP"
+       exit 1
+fi
+DEFECTS=$TEMP/defects; rm -f $DEFECTS
+REPORT=$TEMP/report; rm -f $REPORT
+TAPELIST=
+EXITSTAT=$TEMP/amrecover.exit; rm -rf $EXITSTAT
+
+trap 'report "aborted!"; echo "aborted!" >> $DEFECTS; sendreport; rm -fr $TEMP; exit 1' 1 2 3 4 5 6 7 8 10 12 13 14 15
+
+$Echoe "Defects file is $DEFECTS"
+report "amverify $CONFIG"
+report "`date`"
+report ""
+
+# ----------------------------------------------------------------------------
+
+while [ $SLOT -lt $SLOTS ]; do
+       SLOT=`expr $SLOT + 1`
+       #
+       # Tape Changer: dial slot
+       #
+       if [ X"$TPCHANGER" != X"" ]; then
+               report "Loading ${CHANGER_SLOT} slot..."
+               $AMTAPE $CONFIG slot $CHANGER_SLOT > $TEMP/amtape.out 2>&1
+               THIS_SLOT=$CHANGER_SLOT
+               CHANGER_SLOT=next
+               RESULT=`grep "changed to slot" $TEMP/amtape.out`
+               [ X"$RESULT" = X"" ] \
+                       && report "** Error loading slot $THIS_SLOT" \
+                       && report "`cat $TEMP/amtape.out`" \
+                       && cat $TEMP/amtape.out >> $DEFECTS \
+                       && continue
+               DEVICE=`$AMTAPE $CONFIG device`
+       fi
+       report "Using device $DEVICE"
+       $Echon "Waiting for device to go ready..."
+       until eval $DEVICE_READY >/dev/null 2>&1; do
+               sleep 3
+       done
+       $Echon "Rewinding..."
+       until $MT $MTF $DEVICE rewind; do
+               sleep 3
+       done
+       $Echon "Processing label..."
+       $DD if=$DEVICE count=1 bs=@MAXTAPEBLOCKSIZE@k 2> $TEMP/errors > $TEMP/header
+       [ ! -s $TEMP/header ] \
+               && report "** Error reading label on tape" \
+               && cat $TEMP/errors >> $DEFECTS \
+               && continue
+       TAPENDATE=`sed 1q < $TEMP/header | grep '^AMANDA: TAPESTART'`
+       [ X"$TAPENDATE" = X"" ] \
+               && report "** No amanda tape in slot" \
+               && continue
+       set X $TAPENDATE
+       shift
+       shift                   # "AMANDA:"
+       shift                   # "TAPESTART"
+       VOLUME=$4
+       DWRITTEN=$2
+       report "Volume $VOLUME, Date $DWRITTEN"
+       [ X"$DWRITTEN" = X"0" -o X"$DWRITTEN" = X"X" ] \
+               && report "Fresh tape. Skipping..." \
+               && continue
+       TAPELIST="$TAPELIST $VOLUME"
+       $Echon "Rewinding..."
+       until $MT $MTF $DEVICE rewind; do
+               sleep 3
+       done
+       ERG=0
+       ERRORS=0
+       while [ $ERG = 0 ]; do
+               if [ $Echon = echon ]; then
+                       $Echon "Waiting for device to go ready..."
+               fi
+               until eval $DEVICE_READY >/dev/null 2>&1; do
+                       sleep 3
+               done
+               if [ $Echon = echon ]; then
+                       $Echon "Reading..."
+               fi
+               RESULT=`$AMRESTORE -h -p $DEVICE 2> $TEMP/amrestore.out \
+                       | doonefile 2> $TEMP/onefile.errors`
+               FILE=`grep restoring $TEMP/amrestore.out \
+                       | sed 's/^.*restoring //'`
+               EOF=`grep "reached end of tape" $TEMP/amrestore.out`
+               # amrestore:   0: restoring sundae._mnt_sol1_usr.19961127.1
+               if [ X"$FILE" != X"" -a X"$RESULT" = X"0" ]; then
+                       report "Checked $FILE"
+               elif [ X"$FILE" != X"" -a X"$RESULT" = X"999" ]; then
+                       report "Skipped $FILE (`cat $TEMP/errors`)"
+               elif [ -n "$EOF" ]; then
+                       report "End-of-Tape detected."
+                       break
+               else
+                       report "** Error detected ($FILE)"
+                       echo "$VOLUME ($FILE):" >>$DEFECTS
+                       [ -s $TEMP/amrestore.out ] \
+                               && report "`cat $TEMP/amrestore.out`" \
+                               && cat $TEMP/amrestore.out >>$DEFECTS
+                       [ -s $TEMP/errors ] \
+                               && report "`cat $TEMP/errors`" \
+                               && cat $TEMP/errors >>$DEFECTS
+                       [ -s $TEMP/onefile.errors ] \
+                               && report "`cat $TEMP/onefile.errors`" \
+                               && cat $TEMP/onefile.errors >>$DEFECTS
+                       ERRORS=`expr $ERRORS + 1`
+                       [ $ERRORS -gt 5 ] \
+                               && report "Too many errors." \
+                               && break
+               fi
+       done
+       $Echon "Rewinding..."
+       until $MT $MTF $DEVICE rewind; do
+               sleep 3
+       done
+       rm -f $TEMP/header \
+             $TEMP/amtape.out \
+             $TEMP/amrestore.out \
+             $TEMP/errors \
+             $TEMP/onefile.errors
+done
+
+[ -s $DEFECTS ] \
+       && $Echoe "Errors found: " \
+       && cat $DEFECTS
+
+sendreport
+
+exit 0
diff --git a/server-src/amverifyrun.sh.in b/server-src/amverifyrun.sh.in
new file mode 100644 (file)
index 0000000..4404e1b
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libexecdir=@libexecdir@
+
+PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb
+export PATH
+
+USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
+if [ "$USE_VERSION_SUFFIXES" = "yes" ]; then
+        SUF="-@VERSION@"
+else
+        SUF=
+fi
+
+getparm() {
+        $AMGETCONF $CONFIG $1 2>/dev/null | grep -v BUGGY
+}
+
+CONFIG=$1
+libexecdir=$libexecdir  
+sbindir=$sbindir
+AMGETCONF=$sbindir/amgetconf$SUF
+AMVERIFY=$sbindir/amverify$SUF
+LOGDIR=`getparm logdir`
+AMDUMPLOG=${LOGDIR}/amdump.1
+AMFLUSHLOG=${LOGDIR}/amflush.1
+if [ -f $AMDUMPLOG ]; then
+  if [ -f $AMFLUSHLOG ]; then
+    if [ $AMDUMPLOG -nt $AMFLUSHLOG ]; then
+      AMLOG=$AMDUMPLOG
+    else
+      AMLOG=$AMFLUSHLOG
+    fi
+  else
+    AMLOG=$AMDUMPLOG
+  fi
+else
+  if [ -f $AMFLUSHLOG ]; then
+    AMLOG=$AMFLUSHLOG
+  else
+    echo "Nothing to verify"
+    exit 1;
+  fi
+fi
+
+
+FIRST_SLOT=`grep "taper: slot" $AMLOG | sed 1q | sed 's/://g' | awk '{print $3}'`
+if [ X"$FIRST_SLOT" = X"" ]; then
+  FIRST_SLOT='-1'
+fi
+
+NBTAPES=`grep -c "taper: wrote label " $AMLOG`
+
+$AMVERIFY $CONFIG $FIRST_SLOT $NBTAPES
diff --git a/server-src/changer.c b/server-src/changer.c
new file mode 100644 (file)
index 0000000..9a0cff0
--- /dev/null
@@ -0,0 +1,542 @@
+/*
+ * 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: changer.c,v 1.14.4.6.4.1.2.3 2003/02/28 19:23:25 martinea Exp $
+ *
+ * interface routines for tape changers
+ */
+#include "amanda.h"
+#include "conffile.h"
+#include "version.h"
+
+#include "changer.h"
+
+/*
+ * If we don't have the new-style wait access functions, use our own,
+ * compatible with old-style BSD systems at least.  Note that we don't
+ * care about the case w_stopval == WSTOPPED since we don't ask to see
+ * stopped processes, so should never get them from wait.
+ */
+#ifndef WEXITSTATUS
+#   define WEXITSTATUS(r)       (((union wait *) &(r))->w_retcode)
+#   define WTERMSIG(r)          (((union wait *) &(r))->w_termsig)
+
+#   undef  WIFSIGNALED
+#   define WIFSIGNALED(r)       (((union wait *) &(r))->w_termsig != 0)
+#endif
+
+
+int changer_debug = 0;
+char *changer_resultstr = NULL;
+
+static char *tapechanger = NULL;
+
+/* local functions */
+static int changer_command P((char *cmd, char *arg));
+
+int changer_init()
+{
+    tapechanger = getconf_str(CNF_TPCHANGER);
+    return strcmp(tapechanger, "") != 0;
+}
+
+
+static int report_bad_resultstr()
+{
+    char *s;
+
+    s = vstralloc("badly formed result from changer: ",
+                 "\"", changer_resultstr, "\"",
+                 NULL);
+    amfree(changer_resultstr);
+    changer_resultstr = s;
+    return 2;
+}
+
+static int run_changer_command(cmd, arg, slotstr, rest)
+char *cmd;
+char *arg;
+char **slotstr;
+char **rest;
+{
+    int exitcode;
+    char *result_copy;
+    char *slot;
+    char *s;
+    int ch;
+
+    *slotstr = NULL;
+    *rest = NULL;
+    exitcode = changer_command(cmd, arg);
+    s = changer_resultstr;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') return report_bad_resultstr();
+    slot = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    *slotstr = newstralloc(*slotstr, slot);
+    s[-1] = ch;
+
+    skip_whitespace(s, ch);
+    *rest = s - 1;
+
+    if(exitcode) {
+       if(ch == '\0') return report_bad_resultstr();
+       result_copy = stralloc(s - 1);
+       amfree(changer_resultstr);
+       changer_resultstr = result_copy;
+       return exitcode;
+    }
+    return 0;
+}
+
+int changer_reset(slotstr)
+char **slotstr;
+{
+    char *rest;
+
+    return run_changer_command("-reset", (char *) NULL, slotstr, &rest);
+}
+
+int changer_clean(slotstr)
+char **slotstr;
+{
+    char *rest;
+
+    return run_changer_command("-clean", (char *) NULL, slotstr, &rest);
+}
+
+int changer_eject(slotstr)
+char **slotstr;
+{
+    char *rest;
+
+    return run_changer_command("-eject", (char *) NULL, slotstr, &rest);
+}
+
+int changer_loadslot(inslotstr, outslotstr, devicename)
+char *inslotstr, **outslotstr, **devicename;
+{
+    char *rest;
+    int rc;
+
+    rc = run_changer_command("-slot", inslotstr, outslotstr, &rest);
+    if(rc) return rc;
+
+    if(*rest == '\0') return report_bad_resultstr();
+
+    *devicename = newstralloc(*devicename, rest);
+    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;
+{
+    char *rest;
+    int rc;
+
+    rc = run_changer_command("-info", (char *) NULL, curslotstr, &rest);
+    if(rc) return rc;
+
+    dbprintf(("changer_query: changer return was %s\n",rest));
+    if (sscanf(rest, "%d %d %d", nslotsp, backwardsp, searchable) != 3) {
+      if (sscanf(rest, "%d %d", nslotsp, backwardsp) != 2) {
+        return report_bad_resultstr();
+      } else {
+        *searchable = 0;
+      }
+    }
+    dbprintf(("changer_query: searchable = %d\n",*searchable));
+    return 0;
+}
+
+int changer_info(nslotsp, curslotstr, backwardsp)
+int *nslotsp, *backwardsp;
+char **curslotstr;
+{
+    char *rest;
+    int rc;
+
+    rc = run_changer_command("-info", (char *) NULL, curslotstr, &rest);
+    if(rc) return rc;
+
+    if (sscanf(rest, "%d %d", nslotsp, backwardsp) != 2) {
+       return report_bad_resultstr();
+    }
+    return 0;
+}
+
+
+/* ---------------------------- */
+
+void changer_scan(user_init, user_slot)
+int (*user_init) P((int rc, int nslots, int backwards));
+int (*user_slot) P((int rc, char *slotstr, char *device));
+{
+    char *slotstr, *device = NULL, *curslotstr = NULL;
+    int nslots, checked, backwards, rc, done;
+
+    rc = changer_info(&nslots, &curslotstr, &backwards);
+    done = user_init(rc, nslots, backwards);
+    amfree(curslotstr);
+
+    slotstr = "current";
+    checked = 0;
+
+    while(!done && checked < nslots) {
+       rc = changer_loadslot(slotstr, &curslotstr, &device);
+       if(rc > 0)
+           done = user_slot(rc, curslotstr, device);
+       else if(!done)
+           done = user_slot(0,  curslotstr, device);
+       amfree(curslotstr);
+       amfree(device);
+
+       checked += 1;
+       slotstr = "next";
+    }
+}
+
+/* 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 like 
+   in changer_scan.
+*/
+void changer_find(user_init, user_slot, searchlabel)
+int (*user_init) P((int rc, int nslots, int backwards));
+int (*user_slot) P((int rc, char *slotstr, char *device));
+char *searchlabel;
+{
+    char *slotstr, *device = NULL, *curslotstr = NULL;
+    int nslots, checked, backwards, rc, done, searchable;
+
+    rc = changer_query(&nslots, &curslotstr, &backwards, &searchable);
+    done = user_init(rc, nslots, backwards);
+    amfree(curslotstr);
+   
+    if (searchlabel != NULL)
+    {
+      dbprintf(("changer_find: looking for %s changer is searchable = %d\n",
+               searchlabel, searchable));
+    } else {
+      dbprintf(("changer_find: looking for NULL changer is searchable = %d\n",
+               searchable));
+    }
+
+    if ((searchlabel!=NULL) && searchable && !done){
+      rc=changer_search(searchlabel,&curslotstr,&device);
+      if(rc == 0)
+        done = user_slot(rc,curslotstr,device);
+    }
+    slotstr = "current";
+    checked = 0;
+
+    while(!done && checked < nslots) {
+       rc = changer_loadslot(slotstr, &curslotstr, &device);
+       if(rc > 0)
+           done = user_slot(rc, curslotstr, device);
+       else if(!done)
+           done = user_slot(0,  curslotstr, device);
+       amfree(curslotstr);
+       amfree(device);
+
+       checked += 1;
+       slotstr = "next";
+    }
+}
+
+/* ---------------------------- */
+
+void changer_current(user_init, user_slot)
+int (*user_init) P((int rc, int nslots, int backwards));
+int (*user_slot) P((int rc, char *slotstr, char *device));
+{
+    char *device = NULL, *curslotstr = NULL;
+    int nslots, backwards, rc, done;
+
+    rc = changer_info(&nslots, &curslotstr, &backwards);
+    done = user_init(rc, nslots, backwards);
+    amfree(curslotstr);
+
+    rc = changer_loadslot("current", &curslotstr, &device);
+    if(rc > 0) {
+       done = user_slot(rc, curslotstr, device);
+    } else if(!done) {
+       done = user_slot(0,  curslotstr, device);
+    }
+    amfree(curslotstr);
+    amfree(device);
+}
+
+/* ---------------------------- */
+
+static int changer_command(cmd, arg)
+     char *cmd;
+     char *arg;
+{
+    int fd[2];
+    amwait_t wait_exitcode;
+    int exitcode;
+    char num1[NUM_STR_SIZE];
+    char num2[NUM_STR_SIZE];
+    char *cmdstr;
+    pid_t pid, changer_pid;
+
+    if (*tapechanger != '/') {
+       tapechanger = vstralloc(libexecdir, "/", tapechanger, versionsuffix(),
+                               NULL);
+       malloc_mark(tapechanger);
+    }
+    cmdstr = vstralloc(tapechanger, " ",
+                      cmd, arg ? " " : "", 
+                      arg ? arg : "",
+                      NULL);
+
+    if(changer_debug) {
+       fprintf(stderr, "changer: opening pipe to: %s\n", cmdstr);
+       fflush(stderr);
+    }
+
+    amfree(changer_resultstr);
+
+    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
+       changer_resultstr = vstralloc ("<error> ",
+                                      "could not create pipe for \"",
+                                      cmdstr,
+                                      "\": ",
+                                      strerror(errno),
+                                      NULL);
+       exitcode = 2;
+       goto failed;
+    }
+    if(fd[0] < 0 || fd[0] >= FD_SETSIZE) {
+       ap_snprintf(num1, sizeof(num1), "%d", fd[0]);
+       ap_snprintf(num2, sizeof(num2), "%d", FD_SETSIZE-1);
+       changer_resultstr = vstralloc ("<error> ",
+                                      "could not create pipe for \"",
+                                      cmdstr,
+                                      "\": ",
+                                      "socketpair 0: descriptor ",
+                                      num1,
+                                      " out of range ( .. ",
+                                      num2,
+                                      ")",
+                                      NULL);
+       exitcode = 2;
+       goto done;
+    }
+    if(fd[1] < 0 || fd[1] >= FD_SETSIZE) {
+       ap_snprintf(num1, sizeof(num1), "%d", fd[1]);
+       ap_snprintf(num2, sizeof(num2), "%d", FD_SETSIZE-1);
+       changer_resultstr = vstralloc ("<error> ",
+                                      "could not create pipe for \"",
+                                      cmdstr,
+                                      "\": ",
+                                      "socketpair 1: descriptor ",
+                                      num1,
+                                      " out of range ( .. ",
+                                      num2,
+                                      ")",
+                                      NULL);
+       exitcode = 2;
+       goto done;
+    }
+
+    switch(changer_pid = fork()) {
+    case -1:
+       changer_resultstr = vstralloc ("<error> ",
+                                      "could not fork for \"",
+                                      cmdstr,
+                                      "\": ",
+                                      strerror(errno),
+                                      NULL);
+       exitcode = 2;
+       goto done;
+    case 0:
+       if(dup2(fd[1], 1) == -1 || dup2(fd[1], 2) == -1) {
+           changer_resultstr = vstralloc ("<error> ",
+                                          "could not open pipe to \"",
+                                          cmdstr,
+                                          "\": ",
+                                          strerror(errno),
+                                          NULL);
+           (void)write(fd[1], changer_resultstr, strlen(changer_resultstr));
+           exit(1);
+       }
+       aclose(fd[0]);
+       aclose(fd[1]);
+       if(config_dir && chdir(config_dir) == -1) {
+           changer_resultstr = vstralloc ("<error> ",
+                                          "could not cd to \"",
+                                          config_dir,
+                                          "\": ",
+                                          strerror(errno),
+                                          NULL);
+           (void)write(2, changer_resultstr, strlen(changer_resultstr));
+           exit(1);
+       }
+       if(arg) {
+           execle(tapechanger, tapechanger, cmd, arg, NULL, safe_env());
+       } else {
+           execle(tapechanger, tapechanger, cmd, NULL, safe_env());
+       }
+       changer_resultstr = vstralloc ("<error> ",
+                                      "could not exec \"",
+                                      tapechanger,
+                                      "\": ",
+                                      strerror(errno),
+                                      NULL);
+       (void)write(2, changer_resultstr, strlen(changer_resultstr));
+       exit(1);
+    default:
+       aclose(fd[1]);
+    }
+
+    if((changer_resultstr = areads(fd[0])) == NULL) {
+       changer_resultstr = vstralloc ("<error> ",
+                                      "could not read result from \"",
+                                      tapechanger,
+                                      errno ? "\": " : "\"",
+                                      errno ? strerror(errno) : "",
+                                      NULL);
+    }
+
+    while(1) {
+       if ((pid = wait(&wait_exitcode)) == -1) {
+           if(errno == EINTR) {
+               continue;
+           } else {
+               changer_resultstr = vstralloc ("<error> ",
+                                              "wait for \"",
+                                              tapechanger,
+                                              "\" failed: ",
+                                              strerror(errno),
+                                              NULL);
+               exitcode = 2;
+               goto done;
+           }
+       } else if (pid != changer_pid) {
+           ap_snprintf(num1, sizeof(num1), "%ld", (long)pid);
+           changer_resultstr = vstralloc ("<error> ",
+                                          "wait for \"",
+                                          tapechanger,
+                                          "\" returned unexpected pid ",
+                                          num1,
+                                          NULL);
+           exitcode = 2;
+           goto done;
+       } else {
+           break;
+       }
+    }
+
+    /* mark out-of-control changers as fatal error */
+    if(WIFSIGNALED(wait_exitcode)) {
+       ap_snprintf(num1, sizeof(num1), "%d", WTERMSIG(wait_exitcode));
+       changer_resultstr = newvstralloc (changer_resultstr,
+                                         "<error> ",
+                                         changer_resultstr,
+                                         " (got signal ", num1, ")",
+                                         NULL);
+       exitcode = 2;
+    } else {
+       exitcode = WEXITSTATUS(wait_exitcode);
+    }
+
+done:
+    aclose(fd[0]);
+    aclose(fd[1]);
+
+failed:
+    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;
+{
+    char *rest;
+    int rc;
+
+    dbprintf(("changer_search: %s\n",searchlabel));
+    rc = run_changer_command("-search", searchlabel, outslotstr, &rest);
+    if(rc) return rc;
+
+    if(*rest == '\0') return report_bad_resultstr();
+
+    *devicename = newstralloc(*devicename, rest);
+    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;
+{
+    int rc;
+    char *rest=NULL;
+    char *slotstr;
+    char *curslotstr = NULL;
+    int nslots, backwards, searchable;
+
+    dbprintf(("changer_label: %s for slot %s\n",labelstr,slotsp));
+    rc = changer_query(&nslots, &curslotstr, &backwards,&searchable);
+    amfree(curslotstr);
+
+    if ((rc == 0) && (searchable == 1)){
+       dbprintf(("changer_label: calling changer -label %s\n",labelstr));
+       rc = run_changer_command("-label", labelstr, &slotstr, &rest);
+       amfree(slotstr);
+    }
+
+    if(rc) return rc;
+
+    return 0;
+}
diff --git a/server-src/changer.h b/server-src/changer.h
new file mode 100644 (file)
index 0000000..09d9ee9
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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: changer.h,v 1.6.4.3 1999/09/08 23:27:53 jrj Exp $
+ *
+ * interface routines for tape changers
+ */
+#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((int (*user_init)(int rc, int nslots, int backwards),
+                    int (*user_slot)(int rc, char *slotstr, char *device)));
+void changer_scan P((int (*user_init)(int rc, int nslots, int backwards),
+                    int (*user_slot)(int rc, char *slotstr, char *device)));
+void changer_find P((int (*user_init)(int rc, int nslots, int backwards),
+                    int (*user_slot)(int rc, char *slotstr, char *device),
+                     char *searchlabel));
diff --git a/server-src/conffile.c b/server-src/conffile.c
new file mode 100644 (file)
index 0000000..62e1762
--- /dev/null
@@ -0,0 +1,3102 @@
+/*
+ * 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: conffile.c,v 1.54.2.16.2.5.2.20 2003/11/26 16:12:19 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 "conffile.h"
+#include "diskfile.h"
+#include "driverio.h"
+#include "clock.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+
+#define BIGINT 1000000000              /* 2 million yrs @ 1 per day */
+
+/* internal types and variables */
+
+/*
+ * XXX - this is used by the krb4 stuff.
+ * Hopefully nobody will need this here.  (not very likely).  -kovert
+ */
+#if defined(INTERFACE)
+#  undef INTERFACE
+#endif
+
+typedef enum {
+    UNKNOWN, ANY, COMMA, LBRACE, RBRACE, NL, END,
+    IDENT, INT, BOOL, REAL, STRING, TIME,
+
+    /* config parameters */
+    INCLUDEFILE,
+    ORG, MAILTO, DUMPUSER,
+    TAPECYCLE, TAPEDEV, CHNGRDEV, CHNGRFILE, LABELSTR,
+    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,
+
+    TAPERALGO, FIRST, FIRSTFIT, LARGEST, LARGESTFIT, SMALLEST, LAST,
+
+    /* holding disk */
+    COMMENT, DIRECTORY, USE, CHUNKSIZE,
+
+    /* dump type */
+    /*COMMENT,*/ PROGRAM, DUMPCYCLE, RUNSPERCYCLE, MAXCYCLE, MAXDUMPS,
+    OPTIONS, PRIORITY, FREQUENCY, INDEX, MAXPROMOTEDAY,
+    STARTTIME, COMPRESS, AUTH, STRATEGY,
+    SKIP_INCR, SKIP_FULL, RECORD, HOLDING,
+    EXCLUDE, INCLUDE, KENCRYPT, IGNORE, COMPRATE,
+
+    /* tape type */
+    /*COMMENT,*/ BLOCKSIZE, FILE_PAD, LBL_TEMPL, FILEMARK, LENGTH, SPEED,
+
+    /* network interface */
+    /*COMMENT, USE,*/
+
+    /* dump options (obsolete) */
+    EXCLUDE_FILE, EXCLUDE_LIST,
+
+    /* compress */
+    NONE, FAST, BEST, SERVER, CLIENT,
+
+    /* priority */
+    LOW, MEDIUM, HIGH,
+
+    /* authentication */
+    KRB4_AUTH, BSD_AUTH,
+
+    /* 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;
+    double r;
+    char *s;
+} val_t;
+
+/* this corresponds to the normal output of amanda, but may
+ * be adapted to any spacing as you like.
+ */
+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",      0, 7,  0,  0, "%*.*f",  "OUT-KB" },
+    { "Compress",   0, 6,  1,  0, "%*.*f",  "COMP%" },
+    { "DumpTime",   0, 7,  7,  0, "%*.*s",  "MMM:SS" },
+    { "DumpRate",   0, 6,  1,  0, "%*.*f",  "KB/s" },
+    { "TapeTime",   1, 6,  6,  0, "%*.*s",  "MMM:SS" },
+    { "TapeRate",   0, 6,  1,  0, "%*.*f",  "KB/s" },
+    { NULL,         0, 0,  0,  0, NULL,     NULL }
+};
+
+char *config_name = NULL;
+char *config_dir = NULL;
+
+/* visible holding disk variables */
+
+holdingdisk_t *holdingdisks;
+int num_holdingdisks;
+
+/* 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_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;
+
+/* reals */
+static val_t conf_bumpmult;
+
+/* other internal variables */
+static holdingdisk_t hdcur;
+
+static tapetype_t tpcur;
+
+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_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 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_priority P((void));
+static void get_auth P((void));
+static void get_strategy 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_number 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));
+
+/*
+** ------------------------
+**  External entry points
+** ------------------------
+*/
+
+int read_conffile(filename)
+char *filename;
+{
+    interface_t *ip;
+
+    init_defaults();
+
+    /* We assume that confname & conf are initialized to NULL above */
+    read_conffile_recursively(filename);
+
+    if(got_parserror != -1 ) {
+       if(lookup_tapetype(conf_tapetype.s) == NULL) {
+           char *save_confname = confname;
+
+           confname = filename;
+           if(!seen_tapetype)
+               parserror("default tapetype %s not defined", conf_tapetype.s);
+           else {
+               line_num = seen_tapetype;
+               parserror("tapetype %s not defined", conf_tapetype.s);
+           }
+           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->curusage = 0;
+    ip->next = interface_list;
+    interface_list = ip;
+
+    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 },
+    { "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 },
+    { "AUTOFLUSH", CNF_AUTOFLUSH, BOOL },
+    { "RESERVE", CNF_RESERVE, INT },
+    { "MAXDUMPSIZE", CNF_MAXDUMPSIZE, INT },
+    { NULL }
+};
+
+char *getconf_byname(str)
+char *str;
+{
+    static char *tmpstr;
+    char number[NUM_STR_SIZE];
+    struct byname *np;
+    char *s;
+    char ch;
+
+    tmpstr = stralloc(str);
+    s = tmpstr;
+    while((ch = *s++) != '\0') {
+       if(islower((int) ch)) s[-1] = toupper(ch);
+    }
+
+    for(np = byname_table; np->name != NULL; np++)
+       if(strcmp(np->name, tmpstr) == 0) break;
+
+    if(np->name == NULL) return NULL;
+
+    if(np->typ == INT) {
+       ap_snprintf(number, sizeof(number), "%d", getconf_int(np->parm));
+       tmpstr = newstralloc(tmpstr, number);
+    } else if(np->typ == REAL) {
+       ap_snprintf(number, sizeof(number), "%f", getconf_real(np->parm));
+       tmpstr = newstralloc(tmpstr, number);
+    } else {
+       tmpstr = newstralloc(tmpstr, getconf_str(np->parm));
+    }
+
+    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_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;
+    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_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_MAXDUMPSIZE: r = conf_maxdumpsize.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;
+
+    default:
+       error("error [unknown getconf_int parm: %d]", parm);
+       /* NOTREACHED */
+    }
+    return r;
+}
+
+double getconf_real(parm)
+confparm_t parm;
+{
+    double r = 0;
+
+    switch(parm) {
+
+    case CNF_BUMPMULT: r = conf_bumpmult.r; break;
+
+    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;
+
+    default:
+       error("error [unknown getconf_str parm: %d]", parm);
+       /* NOTREACHED */
+    }
+    return r;
+}
+
+holdingdisk_t *getconf_holdingdisks()
+{
+    return holdingdisks;
+}
+
+dumptype_t *lookup_dumptype(str)
+char *str;
+{
+    dumptype_t *p;
+
+    for(p = dumplist; p != NULL; p = p->next) {
+       if(strcmp(p->name, str) == 0) return p;
+    }
+    return NULL;
+}
+
+tapetype_t *lookup_tapetype(str)
+char *str;
+{
+    tapetype_t *p;
+
+    for(p = tapelist; p != NULL; p = p->next) {
+       if(strcmp(p->name, str) == 0) return p;
+    }
+    return NULL;
+}
+
+interface_t *lookup_interface(str)
+char *str;
+{
+    interface_t *p;
+
+    if(str == NULL) return interface_list;
+    for(p = interface_list; p != NULL; p = p->next) {
+       if(strcmp(p->name, str) == 0) return p;
+    }
+    return NULL;
+}
+
+
+/*
+** ------------------------
+**  Internal routines
+** ------------------------
+*/
+
+
+static void init_defaults()
+{
+    char *s;
+
+    /* defaults for exported variables */
+
+#ifdef DEFAULT_CONFIG
+    s = DEFAULT_CONFIG;
+#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);
+#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);
+#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_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_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.i = -1;
+    conf_amrecover_do_fsf.i = 0;
+    conf_amrecover_check_label.i = 0;
+    conf_taperalgo.i = 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_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;
+    line_num = got_parserror = 0;
+    allow_overwrites = 0;
+    token_pushed = 0;
+
+    while(holdingdisks != NULL) {
+       holdingdisk_t *hp;
+
+       hp = holdingdisks;
+       holdingdisks = holdingdisks->next;
+       amfree(hp);
+    }
+    num_holdingdisks = 0;
+
+    /* free any previously declared dump, tape and interface types */
+
+    while(dumplist != NULL) {
+       dumptype_t *dp;
+
+       dp = dumplist;
+       dumplist = dumplist->next;
+       amfree(dp);
+    }
+    while(tapelist != NULL) {
+       tapetype_t *tp;
+
+       tp = tapelist;
+       tapelist = tapelist->next;
+       amfree(tp);
+    }
+    while(interface_list != NULL) {
+       interface_t *ip;
+
+       ip = interface_list;
+       interface_list = interface_list->next;
+       amfree(ip);
+    }
+
+    /* 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;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "COMPRESS-FAST"; dpcur.seen = -1;
+    dpcur.compress = COMP_FAST; dpcur.s_compress = -1;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "COMPRESS-BEST"; dpcur.seen = -1;
+    dpcur.compress = COMP_BEST; dpcur.s_compress = -1;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "SRVCOMPRESS"; dpcur.seen = -1;
+    dpcur.compress = COMP_SERV_FAST; dpcur.s_compress = -1;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "BSD-AUTH"; dpcur.seen = -1;
+    dpcur.auth = AUTH_BSD; dpcur.s_auth = -1;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "KRB4-AUTH"; dpcur.seen = -1;
+    dpcur.auth = AUTH_KRB4; dpcur.s_auth = -1;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "NO-RECORD"; dpcur.seen = -1;
+    dpcur.record = 0; dpcur.s_record = -1;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "NO-HOLD"; dpcur.seen = -1;
+    dpcur.no_hold = 1; dpcur.s_no_hold = -1;
+    save_dumptype();
+
+    init_dumptype_defaults();
+    dpcur.name = "NO-FULL"; dpcur.seen = -1;
+    dpcur.strategy = DS_NOFULL; dpcur.s_strategy = -1;
+    save_dumptype();
+}
+
+static void read_conffile_recursively(filename)
+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;
+
+    if (*filename == '/' || config_dir == NULL) {
+       confname = stralloc(filename);
+    } else {
+       confname = stralloc2(config_dir, filename);
+    }
+
+    if((conf = fopen(confname, "r")) == NULL) {
+       fprintf(stderr, "could not open conf file \"%s\": %s\n", confname,
+               strerror(errno));
+       amfree(confname);
+       got_parserror = -1;
+       return;
+    }
+
+    line_num = 0;
+
+    /* read_confline() can invoke us recursively via "includefile" */
+    while(read_confline());
+    afclose(conf);
+
+    amfree(confname);
+
+    /* Restore globals */
+    line_num = save_line_num;
+    conf     = save_conf;
+    confname = save_confname;
+}
+
+
+/* ------------------------ */
+
+
+keytab_t main_keytable[] = {
+    { "BUMPDAYS", BUMPDAYS },
+    { "BUMPMULT", BUMPMULT },
+    { "BUMPSIZE", BUMPSIZE },
+    { "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 },
+    { NULL, IDENT }
+};
+
+static int read_confline()
+{
+    keytable = main_keytable;
+
+    line_num += 1;
+    get_conftoken(ANY);
+    switch(tok) {
+    case INCLUDEFILE:
+       {
+           char *fn;
+
+           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 < 1) {
+                       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 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,INT); 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 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;
+           }
+
+           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_number();
+           i = (i / DISK_BLOCK_KB) * DISK_BLOCK_KB;
+
+           if(!seen_disksize) {
+               conf_disksize.i = i;
+               seen_disksize = line_num;
+           }
+
+           if(holdingdisks != NULL)
+               holdingdisks->disksize = i;
+       }
+
+       break;
+
+    case 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");
+       break;
+
+    case NL:   /* empty line */
+       break;
+    case END:  /* end of file */
+       return 0;
+    default:
+       parserror("configuration keyword expected");
+    }
+    if(tok != NL) get_conftoken(NL);
+    return 1;
+}
+
+keytab_t holding_keytable[] = {
+    { "DIRECTORY", DIRECTORY },
+    { "COMMENT", COMMENT },
+    { "USE", USE },
+    { "CHUNKSIZE", CHUNKSIZE },
+    { NULL, IDENT }
+};
+
+static void get_holdingdisk()
+{
+    int done;
+    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(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, INT);
+           hdcur.disksize = am_floor(hdcur.disksize, DISK_BLOCK_KB);
+           break;
+       case CHUNKSIZE:
+           get_simple((val_t *)&hdcur.chunksize, &hdcur.s_csize, INT);
+           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);
+
+    save_holdingdisk();
+
+    allow_overwrites = save_overwrites;
+    keytable = save_kt;
+}
+
+static void init_holdingdisk_defaults()
+{
+    hdcur.comment = stralloc("");
+    hdcur.diskdir = stralloc(conf_diskdir.s);
+    malloc_mark(hdcur.diskdir);
+    hdcur.disksize = 0;
+    hdcur.chunksize = 1024*1024*1024; /* 1 Gb */
+
+    hdcur.s_comment = 0;
+    hdcur.s_disk = 0;
+    hdcur.s_size = 0;
+    hdcur.s_csize = 0;
+
+    hdcur.up = (void *)0;
+}
+
+static void save_holdingdisk()
+{
+    holdingdisk_t *hp;
+
+    hp = alloc(sizeof(holdingdisk_t));
+    malloc_mark(hp);
+    *hp = hdcur;
+    hp->next = holdingdisks;
+    holdingdisks = hp;
+
+    num_holdingdisks++;
+}
+
+
+keytab_t dumptype_keytable[] = {
+    { "AUTH", AUTH },
+    { "COMMENT", COMMENT },
+    { "COMPRATE", COMPRATE },
+    { "COMPRESS", COMPRESS },
+    { "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 },
+    { NULL, IDENT }
+};
+
+dumptype_t *read_dumptype(name, from, fname, linenum)
+     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;
+
+    if (from) {
+       saved_conf = conf;
+       conf = from;
+    }
+
+    if (fname) {
+       saved_fname = confname;
+       confname = fname;
+    }
+
+    if (linenum)
+       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);
+    }
+
+    dpcur.seen = line_num;
+
+    if (! name) {
+       get_conftoken(LBRACE);
+       get_conftoken(NL);
+    }
+
+    done = 0;
+    do {
+       line_num += 1;
+       get_conftoken(ANY);
+       switch(tok) {
+
+       case AUTH:
+           get_auth();
+           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 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 OPTIONS:
+           get_dumpopts();
+           break;
+       case PRIORITY:
+           get_priority();
+           break;
+       case PROGRAM:
+           get_simple((val_t *)&dpcur.program, &dpcur.s_program, STRING);
+           if(strcmp(dpcur.program, "DUMP")
+              && strcmp(dpcur.program, "GNUTAR"))
+               parserror("backup program \"%s\" unknown", dpcur.program);
+           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 IDENT:
+           copy_dumptype();
+           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();
+
+    allow_overwrites = save_overwrites;
+    keytable = save_kt;
+
+    if (linenum)
+       *linenum = line_num;
+
+    if (fname)
+       confname = saved_fname;
+
+    if (from)
+       conf = saved_conf;
+
+    return lookup_dumptype(dpcur.name);
+}
+
+static void get_dumptype()
+{
+    read_dumptype(NULL, NULL, NULL, NULL);
+}
+
+static void init_dumptype_defaults()
+{
+    dpcur.comment = stralloc("");
+    dpcur.program = stralloc("DUMP");
+    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.start_t = 0;
+
+    dpcur.auth = AUTH_BSD;
+
+    /* options */
+    dpcur.record = 1;
+    dpcur.strategy = DS_STANDARD;
+    dpcur.compress = COMP_FAST;
+    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.s_comment = 0;
+    dpcur.s_program = 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_start_t = 0;
+    dpcur.s_auth = 0;
+    dpcur.s_record = 0;
+    dpcur.s_strategy = 0;
+    dpcur.s_compress = 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;
+}
+
+static void save_dumptype()
+{
+    dumptype_t *dp;
+
+    dp = lookup_dumptype(dpcur.name);
+
+    if(dp != (dumptype_t *)0) {
+       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;
+}
+
+static void copy_dumptype()
+{
+    dumptype_t *dt;
+
+    dt = lookup_dumptype(tokenval.s);
+
+    if(dt == NULL) {
+       parserror("dump type 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_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(start_t, s_start_t);
+    dtcopy(auth, s_auth);
+    dtcopy(record, s_record);
+    dtcopy(strategy, s_strategy);
+    dtcopy(compress, s_compress);
+    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);
+}
+
+keytab_t tapetype_keytable[] = {
+    { "COMMENT", COMMENT },
+    { "LBL-TEMPL", LBL_TEMPL },
+    { "BLOCKSIZE", BLOCKSIZE },
+    { "FILE-PAD", FILE_PAD },
+    { "FILEMARK", FILEMARK },
+    { "LENGTH", LENGTH },
+    { "SPEED", SPEED },
+    { NULL, IDENT }
+};
+
+static void get_tapetype()
+{
+    int done;
+    int save_overwrites;
+    val_t value;
+
+    keytab_t *save_kt;
+
+    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) {
+
+       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, INT);
+           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, INT);
+           if(value.i < 0) {
+               parserror("Tape length must be positive");
+           }
+           else {
+               tpcur.length = value.i;
+           }
+           break;
+       case FILEMARK:
+           get_simple(&value, &tpcur.s_filemark, INT);
+           if(value.i < 0) {
+               parserror("Tape file mark size must be positive");
+           }
+           else {
+               tpcur.filemark = value.i;
+           }
+           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);
+
+    save_tapetype();
+
+    allow_overwrites = save_overwrites;
+    keytable = save_kt;
+}
+
+static void init_tapetype_defaults()
+{
+    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;
+}
+
+static void save_tapetype()
+{
+    tapetype_t *tp;
+
+    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);
+       return;
+    }
+
+    tp = alloc(sizeof(tapetype_t));
+    malloc_mark(tp);
+    *tp = tpcur;
+    tp->next = tapelist;
+    tapelist = tp;
+}
+
+static void copy_tapetype()
+{
+    tapetype_t *tp;
+
+    tp = lookup_tapetype(tokenval.s);
+
+    if(tp == NULL) {
+       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;
+    }
+    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 }
+};
+
+static void get_interface()
+{
+    int done;
+    int save_overwrites;
+    keytab_t *save_kt;
+
+    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(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);
+
+    save_interface();
+
+    allow_overwrites = save_overwrites;
+    keytable = save_kt;
+
+    return;
+}
+
+static void init_interface_defaults()
+{
+    ifcur.comment = stralloc("");
+    ifcur.maxusage = 300;
+
+    ifcur.s_comment = 0;
+    ifcur.s_maxusage = 0;
+
+    ifcur.curusage = 0;
+}
+
+static void save_interface()
+{
+    interface_t *ip;
+
+    ip = lookup_interface(ifcur.name);
+
+    if(ip != (interface_t *)0) {
+       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;
+}
+
+static void copy_interface()
+{
+    interface_t *ip;
+
+    ip = lookup_interface(tokenval.s);
+
+    if(ip == NULL) {
+       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 },
+    { "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 EXCLUDE_FILE:
+           ckseen(&dpcur.s_exclude_file);
+           get_conftoken(STRING);
+           dpcur.exclude_file = append_sl(dpcur.exclude_file, stralloc(tokenval.s));
+           break;
+       case EXCLUDE_LIST:
+           ckseen(&dpcur.s_exclude_list);
+           get_conftoken(STRING);
+           dpcur.exclude_list = append_sl(dpcur.exclude_list, stralloc(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");
+       }
+    } while(!done);
+
+    keytable = save_kt;
+}
+
+static void get_comprate()
+{
+    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");
+    }
+
+    get_conftoken(ANY);
+    switch(tok) {
+    case NL:
+       return;
+    case 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");
+    }
+}
+
+keytab_t compress_keytable[] = {
+    { "BEST", BEST },
+    { "CLIENT", CLIENT },
+    { "FAST", FAST },
+    { "NONE", NONE },
+    { "SERVER", SERVER },
+    { NULL, IDENT }
+};
+
+static void get_compress()
+{
+    keytab_t *save_kt;
+    int serv, clie, none, fast, best;
+    int done;
+    int comp;
+
+    save_kt = keytable;
+    keytable = compress_keytable;
+
+    ckseen(&dpcur.s_compress);
+
+    serv = clie = none = fast = best = 0;
+
+    done = 0;
+    do {
+       get_conftoken(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 NL:     done = 1; break;
+       default:
+           done = 1;
+           serv = clie = 1; /* force an error */
+       }
+    } while(!done);
+
+    if(serv + clie == 0) clie = 1;     /* default to client */
+    if(none + fast + best == 0) fast = 1; /* default to fast */
+
+    comp = -1;
+
+    if(!serv && clie) {
+       if(none && !fast && !best) comp = COMP_NONE;
+       if(!none && fast && !best) comp = COMP_FAST;
+       if(!none && !fast && best) comp = COMP_BEST;
+    }
+
+    if(serv && !clie) {
+       if(none && !fast && !best) comp = COMP_NONE;
+       if(!none && fast && !best) comp = COMP_SERV_FAST;
+       if(!none && !fast && best) comp = COMP_SERV_BEST;
+    }
+
+    if(comp == -1) {
+       parserror("NONE, CLIENT FAST, CLIENT BEST, SERVER FAST or SERVER BEST expected");
+       comp = COMP_NONE;
+    }
+
+    dpcur.compress = comp;
+
+    keytable = save_kt;
+}
+
+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;
+{
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = taperalgo_keytable;
+
+    ckseen(s_taperalgo);
+
+    get_conftoken(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;
+    default:
+       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()
+{
+    int pri;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = priority_keytable;
+
+    ckseen(&dpcur.s_priority);
+
+    get_conftoken(ANY);
+    switch(tok) {
+    case LOW: pri = 0; break;
+    case MEDIUM: pri = 1; break;
+    case HIGH: pri = 2; break;
+    case INT: pri = tokenval.i; break;
+    default:
+       parserror("LOW, MEDIUM, HIGH or integer expected");
+       pri = 0;
+    }
+    dpcur.priority = pri;
+
+    keytable = save_kt;
+}
+
+keytab_t auth_keytable[] = {
+    { "BSD", BSD_AUTH },
+    { "KRB4", KRB4_AUTH },
+    { NULL, IDENT }
+};
+
+static void get_auth()
+{
+    auth_t auth;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = auth_keytable;
+
+    ckseen(&dpcur.s_auth);
+
+    get_conftoken(ANY);
+    switch(tok) {
+    case BSD_AUTH:
+       auth = AUTH_BSD;
+       break;
+    case KRB4_AUTH:
+       auth = AUTH_KRB4;
+       break;
+    default:
+       parserror("BSD or KRB4 expected");
+       auth = AUTH_BSD;
+    }
+    dpcur.auth = auth;
+
+    keytable = save_kt;
+}
+
+keytab_t strategy_keytable[] = {
+    { "HANOI", HANOI },
+    { "NOFULL", NOFULL },
+    { "NOINC", NOINC },
+    { "SKIP", SKIP },
+    { "STANDARD", STANDARD },
+    { "INCRONLY", INCRONLY },
+    { NULL, IDENT }
+};
+
+static void get_strategy()
+{
+    int strat;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = strategy_keytable;
+
+    ckseen(&dpcur.s_strategy);
+
+    get_conftoken(ANY);
+    switch(tok) {
+    case SKIP:
+       strat = DS_SKIP;
+       break;
+    case STANDARD:
+       strat = DS_STANDARD;
+       break;
+    case NOFULL:
+       strat = DS_NOFULL;
+       break;
+    case NOINC:
+       strat = DS_NOINC;
+       break;
+    case HANOI:
+       strat = DS_HANOI;
+       break;
+    case INCRONLY:
+       strat = DS_INCRONLY;
+       break;
+    default:
+       parserror("STANDARD or NOFULL expected");
+       strat = DS_STANDARD;
+    }
+    dpcur.strategy = strat;
+
+    keytable = save_kt;
+}
+
+keytab_t exclude_keytable[] = {
+    { "LIST", LIST },
+    { "FILE", EFILE },
+    { "APPEND", APPEND },
+    { "OPTIONAL", OPTIONAL },
+    { NULL, IDENT }
+};
+
+static void get_exclude()
+{
+    int list, got_one = 0;
+    keytab_t *save_kt;
+    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);
+    }
+    else {
+       list = 0;
+       exclude = dpcur.exclude_file;
+       ckseen(&dpcur.s_exclude_file);
+       if(tok == EFILE) get_conftoken(ANY);
+    }
+
+    if(tok == OPTIONAL) {
+       get_conftoken(ANY);
+       optional = 1;
+    }
+
+    if(tok == APPEND) {
+       get_conftoken(ANY);
+       append = 1;
+    }
+    else {
+       free_sl(exclude);
+       exclude = NULL;
+       append = 0;
+    }
+
+    while(tok == STRING) {
+       exclude = append_sl(exclude, tokenval.s);
+       got_one = 1;
+       get_conftoken(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;
+}
+
+
+static void get_include()
+{
+    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) {
+       list = 1;
+       include = dpcur.include_list;
+       ckseen(&dpcur.s_include_list);
+       get_conftoken(ANY);
+    }
+    else {
+       list = 0;
+       include = dpcur.include_file;
+       ckseen(&dpcur.s_include_file);
+       if(tok == EFILE) get_conftoken(ANY);
+    }
+
+    if(tok == OPTIONAL) {
+       get_conftoken(ANY);
+       optional = 1;
+    }
+
+    if(tok == APPEND) {
+       get_conftoken(ANY);
+       append = 1;
+    }
+    else {
+       free_sl(include);
+       include = NULL;
+       append = 0;
+    }
+
+    while(tok == STRING) {
+       include = append_sl(include, tokenval.s);
+       got_one = 1;
+       get_conftoken(ANY);
+    }
+    unget_conftoken();
+
+    if(got_one == 0) { free_sl(include); include = NULL; }
+
+    if(list == 0)
+       dpcur.include_file = include;
+    else {
+       dpcur.include_list = include;
+       if(!append || optional)
+           dpcur.include_optional = 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_number();
+       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_number()
+{
+    int val;
+    keytab_t *save_kt;
+
+    save_kt = keytable;
+    keytable = numb_keytable;
+
+    get_conftoken(ANY);
+
+    switch(tok) {
+    case INT:
+       val = tokenval.i;
+       break;
+    case INFINITY:
+       val = 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:
+       val *= 7;
+       break;
+    case MULT1M:
+       val *= 1024;
+       break;
+    case MULT1G:
+       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, i, d;
+    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 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.i = 0;
+           do {
+               tokenval.i = tokenval.i * 10 + (ch - '0');
+               ch = getc(conf);
+           } while(isdigit(ch));
+           if(ch != '.') {
+               if(exp != REAL) {
+                   tok = INT;
+                   tokenval.i *= sign;
+               } else {
+                   /* automatically convert to real when expected */
+                   i = tokenval.i;
+                   tokenval.r = sign * (double) i;
+                   tok = REAL;
+               }
+           }
+           else {
+               /* got a real number, not an int */
+               i = tokenval.i;
+               tokenval.r = sign * (double) i;
+               i=0; d=1;
+               ch = getc(conf);
+               while(isdigit(ch)) {
+                   i = i * 10 + (ch - '0');
+                   d = d * 10;
+                   ch = getc(conf);
+               }
+               tokenval.r += sign * ((double)i)/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()
+{
+    return sizeof(ColumnData) / sizeof(ColumnData[0]);
+}
+
+/* conversion from string to table index
+ */
+int StringToColumn(char *s) {
+    int cn;
+    for (cn=0; ColumnData[cn].Name != NULL; cn++) {
+       if (strcasecmp(s, ColumnData[cn].Name) == 0) {
+           break;
+       }
+    }
+    return cn;
+}
+
+char LastChar(char *s) {
+    return s[strlen(s)-1];
+}
+
+int SetColumDataFromString(ColumnInfo* ci, char *s, char **errstr) {
+    /* 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
+     * (maybe) as environment variable.
+     * 
+     * This text should go as comment into the sample amanda.conf
+     *
+     * The format for such a ColumnSpec string s is a ',' seperated
+     * list of triples. Each triple consists of
+     *   -the name of the column (as in ColumnData.Name)
+     *   -prefix before the column
+     *   -the width of the column
+     *       if set to -1 it will be recalculated
+     *  to the maximum length of a line to print.
+     * Example:
+     *         "Disk=1:17,HostName=1:10,OutKB=1:7"
+     * or
+     *         "Disk=1:-1,HostName=1:10,OutKB=1:7"
+     * 
+     * You need only specify those colums that should be changed from
+     * the default. If nothing is specified in the configfile, the
+     * above compiled in values will be in effect, resulting in an
+     * output as it was all the time.
+     *                                                 ElB, 1999-02-24.
+     */
+#ifdef TEST
+    char *myname= "SetColumDataFromString";
+#endif
+
+    while (s && *s) {
+       int Space, Width;
+       int cn;
+       char *eon= strchr(s, '=');
+
+       if (eon == NULL) {
+           *errstr = stralloc2("invalid columnspec: ", s);
+#ifdef TEST
+           fprintf(stderr, "%s: %s\n", myname, *errstr);
+#endif
+           return -1;
+       }
+       *eon= '\0';
+       cn=StringToColumn(s);
+       if (ColumnData[cn].Name == NULL) {
+           *errstr = stralloc2("invalid column name: ", s);
+#ifdef TEST
+           fprintf(stderr, "%s: %s\n", myname, *errstr);
+#endif
+           return -1;
+       }
+       if (sscanf(eon+1, "%d:%d", &Space, &Width) != 2) {
+           *errstr = stralloc2("invalid format: ", eon + 1);
+#ifdef TEST
+           fprintf(stderr, "%s: %s\n", myname, *errstr);
+#endif
+           return -1;
+       }
+       ColumnData[cn].Width= Width;
+       ColumnData[cn].PrefixSpace= Space;
+       if (LastChar(ColumnData[cn].Format) == 's') {
+           if (Width < 0)
+               ColumnData[cn].MaxWidth= 1;
+           else
+               if (Width > ColumnData[cn].Precision)
+                   ColumnData[cn].Precision= Width;
+       }
+       else if (Width < ColumnData[cn].Precision)
+           ColumnData[cn].Precision= Width;
+       s= strchr(eon+1, ',');
+       if (s != NULL)
+           s++;
+    }
+    return 0;
+}
+
+
+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";
+}
+
+
+/* ------------------------ */
+
+
+#ifdef TEST
+
+void
+dump_configuration(filename)
+    char *filename;
+{
+    tapetype_t *tp;
+    dumptype_t *dp;
+    interface_t *ip;
+    holdingdisk_t *hp;
+    time_t st;
+    struct tm *stm;
+
+    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_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  = %d\n", getconf_int(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_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);
+    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(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(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("        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);
+           }
+           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("        COMPRATE %f, %f\n", dp->comprate[0], dp->comprate[1]);
+
+       printf("        OPTIONS: ");
+
+       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_SERV_FAST:
+           printf("SRVCOMP-FAST ");
+           break;
+       case COMP_SERV_BEST:
+           printf("SRVCOMP-BEST ");
+           break;
+       }
+
+       if(!dp->record) printf("NO-");
+       printf("RECORD");
+       if(dp->auth == AUTH_BSD) printf(" BSD-AUTH");
+       else if(dp->auth == AUTH_KRB4) printf(" KRB4-AUTH");
+       else printf(" UNKNOWN-AUTH");
+       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(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);
+    }
+}
+
+int
+main(argc, argv)
+    int argc;
+    char *argv[];
+{
+  char *conffile;
+  char *diskfile;
+  int result;
+  int fd;
+  unsigned long malloc_hist_1, malloc_size_1;
+  unsigned long malloc_hist_2, malloc_size_2;
+
+  for(fd = 3; fd < 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
+     * descriptor, which in turn might be used as an index into
+     * an array (e.g. an fd_set).
+     */
+    close(fd);
+  }
+
+  set_pname("conffile");
+
+  malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+  startclock();
+
+  if (argc > 1) {
+    if (argv[1][0] == '/') {
+      config_dir = stralloc(argv[1]);
+      config_name = strrchr(config_dir, '/') + 1;
+      config_name[-1] = '\0';
+      config_dir = newstralloc2(config_dir, config_dir, "/");
+    } else {
+      config_name = stralloc(argv[1]);
+      config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+    }
+  } else {
+    char my_cwd[STR_SIZE];
+
+    if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+      error("cannot determine current working directory");
+    }
+    config_dir = stralloc2(my_cwd, "/");
+    if ((config_name = strrchr(my_cwd, '/')) != NULL) {
+      config_name = stralloc(config_name + 1);
+    }
+  }
+
+  conffile = stralloc2(config_dir, CONFFILE_NAME);
+  result = read_conffile(conffile);
+  if (result == 0) {
+    diskfile = getconf_str(CNF_DISKFILE);
+    if (diskfile != NULL && access(diskfile, R_OK) == 0) {
+      result = (read_diskfile(diskfile) == NULL);
+    }
+  }
+  dump_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 */
diff --git a/server-src/conffile.h b/server-src/conffile.h
new file mode 100644 (file)
index 0000000..1aecb34
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * 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: conffile.h,v 1.24.2.8.4.4.2.9 2003/01/04 03:35:54 martinea Exp $
+ *
+ * interface for config file reading code
+ */
+#ifndef CONFFILE_H
+#define CONFFILE_H
+
+#include "amanda.h"
+#include "sl.h"
+
+#define CONFFILE_NAME "amanda.conf"
+
+typedef enum conf_e {
+    CNF_ORG,
+    CNF_MAILTO,
+    CNF_DUMPUSER,
+    CNF_TAPEDEV,
+    CNF_CHNGRDEV,
+    CNF_CHNGRFILE,
+    CNF_LABELSTR,
+    CNF_TAPELIST,
+    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_BUMPSIZE,
+    CNF_BUMPMULT,
+    CNF_BUMPDAYS,
+    CNF_TPCHANGER,
+    CNF_RUNTAPES,
+    CNF_MAXDUMPS,
+    CNF_ETIMEOUT,
+    CNF_DTIMEOUT,
+    CNF_CTIMEOUT,
+    CNF_TAPEBUFS,
+    CNF_RAWTAPEDEV,
+    CNF_PRINTER,
+    CNF_AUTOFLUSH,
+    CNF_RESERVE,
+    CNF_MAXDUMPSIZE,
+    CNF_COLUMNSPEC,
+    CNF_AMRECOVER_DO_FSF,
+    CNF_AMRECOVER_CHECK_LABEL,
+    CNF_AMRECOVER_CHANGER,
+    CNF_TAPERALGO
+} confparm_t;
+
+typedef enum auth_e {
+    AUTH_BSD, AUTH_KRB4
+} auth_t;
+
+
+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;
+} tapetype_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 ...) */
+
+/* Compression types */
+#define COMP_NONE      0       /* No compression */
+#define COMP_FAST      1       /* Fast compression on client */
+#define COMP_BEST      2       /* Best compression on client */
+#define COMP_SERV_FAST 3       /* Fast compression on server */
+#define COMP_SERV_BEST 4       /* Best compression on server */
+
+#define ALGO_FIRST     0
+#define ALGO_FIRSTFIT  1
+#define ALGO_LARGEST   2
+#define ALGO_LARGESTFIT        3
+#define ALGO_SMALLEST  4
+#define ALGO_LAST      5
+
+typedef struct dumptype_s {
+    struct dumptype_s *next;
+    int seen;
+    char *name;
+
+    char *comment;
+    char *program;
+    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;
+    int maxpromoteday;
+    auth_t auth;
+    int maxdumps;
+    time_t start_t;
+    int strategy;
+    int compress;
+    float comprate[2]; /* first is full, second is incremental */
+    /* 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_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_auth;
+    int s_maxdumps;
+    int s_maxpromoteday;
+    int s_start_t;
+    int s_strategy;
+    int s_compress;
+    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;
+} dumptype_t;
+
+/* A network interface */
+typedef struct interface_s {
+    struct interface_s *next;
+    int seen;
+    char *name;
+
+    char *comment;
+    int maxusage;              /* bandwidth we can consume [kb/s] */
+
+    /* seen flags */
+    int s_comment;
+    int s_maxusage;
+
+    int curusage;              /* current usage */
+} interface_t;
+
+/* A holding disk */
+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;
+
+    void *up;                  /* generic user pointer */
+} holdingdisk_t;
+
+/* 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
+                        * 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
+                        * to the space needed */
+    char *Format;      /* the printf format string for this
+                        * column element
+                        */
+    char *Title;       /* the title to use for this column */
+} ColumnInfo;
+
+/* this corresponds to the normal output of amanda, but may
+ * be adapted to any spacing as you like.
+ */
+extern ColumnInfo ColumnData[];
+
+extern char *config_name;
+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));
+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));
+
+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));
+
+#endif /* ! CONFFILE_H */
diff --git a/server-src/disk_history.c b/server-src/disk_history.c
new file mode 100644 (file)
index 0000000..21b2c10
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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: disk_history.c,v 1.8.10.1 2002/03/24 19:23:23 jrjackson Exp $
+ *
+ * functions for obtaining backup history
+ */
+
+#include "amanda.h"
+#include "disk_history.h"
+
+static DUMP_ITEM *disk_hist = NULL;
+
+void clear_list P((void))
+{
+    DUMP_ITEM *item, *this;
+
+    item = disk_hist;
+    while (item != NULL)
+    {
+       this = item;
+       item = item->next;
+       amfree(this);
+    }
+    disk_hist = NULL;
+}
+
+/* add item, maintain list ordered by oldest date last */
+void add_dump(date, level, tape, file)
+char *date;
+int level;
+char *tape;
+int file;
+{
+    DUMP_ITEM *new, *item, *before;
+
+    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';
+    new->file = file;
+
+    if (disk_hist == NULL)
+    {
+       disk_hist = new;
+       new->next = NULL;
+       return;
+    }
+
+    if (strcmp(disk_hist->date, new->date) <= 0)
+    {
+       new->next = disk_hist;
+       disk_hist = new;
+       return;
+    }
+
+    before = disk_hist;
+    item = disk_hist->next;
+    while ((item != NULL) && (strcmp(item->date, new->date) > 0))
+    {
+       before = item;
+       item = item->next;
+    }
+    new->next = item;
+    before->next = new;
+}
+
+
+DUMP_ITEM *first_dump P((void))
+{
+    return disk_hist;
+}
+
+DUMP_ITEM *next_dump(item)
+DUMP_ITEM *item;
+{
+    return item->next;
+}
diff --git a/server-src/disk_history.h b/server-src/disk_history.h
new file mode 100644 (file)
index 0000000..6446881
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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: disk_history.h,v 1.3 1998/07/04 00:19:45 oliva Exp $
+ *
+ * interface for obtaining disk backup history
+ */
+
+typedef struct DUMP_ITEM
+{
+    char date[11];
+    int  level;
+    char tape[256];
+    int  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));
+extern DUMP_ITEM *first_dump P((void));
+extern DUMP_ITEM *next_dump P((DUMP_ITEM *item));
diff --git a/server-src/diskfile.c b/server-src/diskfile.c
new file mode 100644 (file)
index 0000000..e2abcf9
--- /dev/null
@@ -0,0 +1,1024 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: diskfile.c,v 1.27.4.6.4.3.2.15 2003/12/16 22:36:45 martinea Exp $
+ *
+ * read disklist file
+ */
+#include "amanda.h"
+#include "arglist.h"
+#include "conffile.h"
+#include "diskfile.h"
+
+
+static disklist_t lst;
+static FILE *diskf;
+static char *diskfname = NULL;
+static host_t *hostlist;
+static int line_num, got_parserror;
+
+/* local functions */
+static char *upcase P((char *st));
+static int read_diskline P((void));
+static void parserror P((char *format, ...))
+    __attribute__ ((format (printf, 1, 2)));
+
+
+disklist_t *read_diskfile(filename)
+char *filename;
+{
+    extern int errno;
+
+    /* initialize */
+
+    hostlist = NULL;
+    lst.head = lst.tail = NULL;
+    diskfname = newstralloc(diskfname, filename);
+    malloc_mark(diskfname);
+    line_num = got_parserror = 0;
+
+    if((diskf = fopen(filename, "r")) == NULL)
+       error("could not open disklist file \"%s\": %s",
+             filename, strerror(errno));
+
+    while(read_diskline());
+    afclose(diskf);
+
+    if(got_parserror) return NULL;
+    else return &lst;
+}
+
+host_t *lookup_host(hostname)
+char *hostname;
+{
+    host_t *p;
+
+    for(p = hostlist; p != NULL; p = p->next) {
+       if(strcasecmp(p->hostname, hostname) == 0) return p;
+    }
+    return NULL;
+}
+
+disk_t *lookup_disk(hostname, diskname)
+char *hostname, *diskname;
+{
+    host_t *host;
+    disk_t *disk;
+
+    host = lookup_host(hostname);
+    if(host == NULL) return NULL;
+
+    for(disk = host->disks; disk != NULL; disk = disk->hostnext) {
+       if(strcmp(disk->name, diskname) == 0) return disk;
+    }
+    return NULL;
+}
+
+void enqueue_disk(list, disk)  /* put disk on end of queue */
+disklist_t *list;
+disk_t *disk;
+{
+    if(list->tail == NULL) list->head = disk;
+    else list->tail->next = disk;
+    disk->prev = list->tail;
+
+    list->tail = disk;
+    disk->next = NULL;
+}
+
+void headqueue_disk(list, disk)        /* put disk on head of queue */
+disklist_t *list;
+disk_t *disk;
+{
+    if(list->head == NULL) list->tail = disk;
+    else list->head->prev = disk;
+    disk->next = list->head;
+
+    list->head = 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));
+{
+    disk_t *prev, *ptr;
+
+    prev = NULL;
+    ptr = list->head;
+
+    while(ptr != NULL) {
+       if(cmp(disk, ptr) < 0) break;
+       prev = ptr;
+       ptr = ptr->next;
+    }
+    disk->next = ptr;
+    disk->prev = prev;
+
+    if(prev == NULL) list->head = disk;
+    else prev->next = disk;
+    if(ptr == NULL) list->tail = disk;
+    else ptr->prev = disk;
+}
+
+disk_t *add_disk(hostname, diskname)
+char *hostname;
+char *diskname;
+{
+    disk_t *disk;
+    host_t *host;
+
+    disk = alloc(sizeof(disk_t));
+    disk->line = 0;
+    disk->name = stralloc(diskname);
+    disk->device = stralloc(diskname);
+    disk->spindle = -1;
+    disk->up = NULL;
+    disk->compress = COMP_NONE;
+    disk->start_t = 0;
+    disk->todo = 1;
+
+    host = lookup_host(hostname);
+    if(host == NULL) {
+       host = alloc(sizeof(host_t));
+       host->next = hostlist;
+       hostlist = host;
+
+       host->hostname = stralloc(hostname);
+       host->disks = NULL;
+       host->inprogress = 0;
+       host->maxdumps = 1;
+       host->netif = NULL;
+       host->start_t = 0;
+       host->up = NULL;
+       host->features = NULL;
+    }
+    enqueue_disk(&lst, disk);
+
+    disk->host = host;
+    disk->hostnext = host->disks;
+    host->disks = disk;
+
+    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 );
+
+    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));
+{
+    disklist_t *tmp;
+    disk_t *disk;
+
+    tmp = in;          /* just in case in == out */
+
+    out->head = (disk_t *)0;
+    out->tail = (disk_t *)0;
+
+    while((disk = dequeue_disk(tmp)))
+       insert_disk(out, disk, cmp);
+}
+
+disk_t *dequeue_disk(list)     /* remove disk from front of queue */
+disklist_t *list;
+{
+    disk_t *disk;
+
+    if(list->head == NULL) return NULL;
+
+    disk = list->head;
+    list->head = disk->next;
+
+    if(list->head == NULL) list->tail = NULL;
+    else list->head->prev = NULL;
+
+    disk->prev = disk->next = NULL;    /* for debugging */
+    return disk;
+}
+
+void remove_disk(list, disk)
+disklist_t *list;
+disk_t *disk;
+{
+    if(disk->prev == NULL) list->head = disk->next;
+    else disk->prev->next = disk->next;
+
+    if(disk->next == NULL) list->tail = disk->prev;
+    else disk->next->prev = disk->prev;
+
+    disk->prev = disk->next = NULL;
+}
+
+static char *upcase(st)
+char *st;
+{
+    char *s = st;
+
+    while(*s) {
+       if(islower((int)*s)) *s = toupper(*s);
+       s++;
+    }
+    return st;
+}
+
+
+static int read_diskline()
+{
+    host_t *host;
+    disk_t *disk;
+    dumptype_t *dtype;
+    interface_t *netif = 0;
+    char *hostname = NULL;
+    char *diskname, *diskdevice;
+    static char *line = NULL;
+    char *s = NULL, *fp;
+    int ch = '\0', dup = 0;
+    char *dn;
+
+    amfree(line);
+    for(; (line = agets(diskf)) != NULL; free(line)) {
+       line_num += 1;
+       s = line;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+       if(ch != '\0' && ch != '#') break;
+    }
+    if(line == NULL) return 0;
+
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    host = lookup_host(fp);
+    if (host == NULL) {
+      hostname = stralloc(fp);
+      malloc_mark(hostname);
+    } else {
+      hostname = host->hostname;
+    }
+
+    skip_whitespace(s, ch);
+    if(ch == '\0' || ch == '#') {
+       parserror("disk device name expected");
+       return 1;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    diskname = stralloc(fp);
+
+    skip_whitespace(s, ch);
+    if(ch == '\0' || ch == '#') {
+       parserror("disk dumptype expected");
+       if(host == NULL) amfree(hostname);
+       amfree(diskname);
+       return 1;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    /* diskdevice */
+    dn = stralloc(fp);
+    if(fp[0] != '{' && (dtype = lookup_dumptype(upcase(fp))) == NULL) {
+       diskdevice = dn;
+       skip_whitespace(s, ch);
+       if(ch == '\0' || ch == '#') {
+           parserror("disk dumptype expected");
+           if(host == NULL) amfree(hostname);
+           amfree(diskname);
+           amfree(diskdevice);
+           return 1;
+       }
+       fp = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+    }
+    else {
+       diskdevice = NULL;
+       amfree(dn);
+    }
+
+    /* check for duplicate disk */
+    if(host && (disk = lookup_disk(hostname, diskname)) != NULL) {
+       parserror("duplicate disk record, previous on line %d", disk->line);
+       dup = 1;
+    } else {
+       disk = alloc(sizeof(disk_t));
+       malloc_mark(disk);
+       disk->line = line_num;
+       disk->name = diskname;
+       disk->device = diskdevice;
+       malloc_mark(disk->name);
+       disk->spindle = -1;
+       disk->up = NULL;
+       disk->inprogress = 0;
+    }
+
+    if (fp[0] == '{') {
+       s[-1] = ch;
+       s = fp+2;
+       skip_whitespace(s, ch);
+       if (ch != '\0' && ch != '#') {
+           parserror("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);
+           if(!dup) {
+               amfree(disk->name);
+               amfree(disk);
+           }
+           return 1;
+       }
+       amfree(line);
+
+       dtype = read_dumptype(vstralloc("custom(", hostname,
+                                       ":", disk->name, ")", 0),
+                             diskf, diskfname, &line_num);
+
+       line = agets(diskf);
+       /* line_num += 1; */ /* read_dumptype did it already */
+
+       if (dtype == NULL || dup) {
+           if(host == NULL) amfree(hostname);
+           if(!dup) {
+             amfree(disk->name);
+             amfree(disk);
+           }
+           return line != NULL;
+       }
+
+       if (line == NULL)
+           line = stralloc("");
+       s = line;
+       ch = *s++;
+    } else if((dtype = lookup_dumptype(upcase(fp))) == NULL) {
+       parserror("undefined dumptype `%s'", fp);
+       if(host == NULL) amfree(hostname);
+       if(!dup) {
+         amfree(disk->name);
+         amfree(disk);
+       }
+       return 1;
+    }
+
+    if (dup) {
+       if(host == NULL) amfree(hostname);
+       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->auth         = dtype->auth;
+    disk->maxdumps     = dtype->maxdumps;
+    disk->maxpromoteday        = dtype->maxpromoteday;
+    disk->start_t      = dtype->start_t;
+    disk->strategy     = dtype->strategy;
+    disk->compress     = dtype->compress;
+    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;
+
+    skip_whitespace(s, ch);
+    fp = s - 1;
+    if(ch && ch != '#') {              /* get optional spindle number */
+       disk->spindle = atoi(fp);
+       skip_integer(s, ch);
+    }
+
+    skip_whitespace(s, ch);
+    fp = s - 1;
+    if(ch && ch != '#') {              /* get optional network interface */
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       if((netif = lookup_interface(upcase(fp))) == NULL) {
+           parserror("undefined network interface `%s'", fp);
+           if(host == NULL) amfree(hostname);
+           amfree(disk->name);
+           amfree(disk);
+           return 1;
+       }
+    } else {
+       netif = lookup_interface("");
+    }
+
+    skip_whitespace(s, ch);
+    if(ch && ch != '#') {              /* now we have garbage, ignore it */
+       parserror("end of line expected");
+    }
+
+    if(dtype->ignore || dtype->strategy == DS_SKIP) {
+       amfree(diskname);
+       free_sl(disk->exclude_file);
+       free_sl(disk->exclude_list);
+       free_sl(disk->include_file);
+       free_sl(disk->include_list);
+       amfree(disk);
+       return 1;
+    }
+
+    /* success, add disk to lists */
+
+    if(host == NULL) {                 /* new host */
+       host = alloc(sizeof(host_t));
+       malloc_mark(host);
+       host->next = hostlist;
+       hostlist = host;
+
+       host->hostname = hostname;
+       hostname = NULL;
+       host->disks = NULL;
+       host->inprogress = 0;
+       host->maxdumps = 1;             /* will be overwritten */
+       host->netif = NULL;
+       host->start_t = 0;
+       host->up = NULL;
+       host->features = NULL;
+    }
+
+    host->netif = netif;
+
+    enqueue_disk(&lst, disk);
+
+    disk->host = host;
+    disk->hostnext = host->disks;
+    host->disks = disk;
+    host->maxdumps = disk->maxdumps;
+
+    return 1;
+}
+
+
+printf_arglist_function(static void parserror, char *, format)
+{
+    va_list argp;
+
+    /* print error message */
+
+    fprintf(stderr, "\"%s\", line %d: ", diskfname, line_num);
+    arglist_start(argp, format);
+    vfprintf(stderr, format, argp);
+    arglist_end(argp);
+    fputc('\n', stderr);
+
+    got_parserror = 1;
+}
+
+
+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;
+{
+    disk_t *d,*p;
+    int pos;
+
+    if(empty(q)) {
+       fprintf(f, "%s QUEUE: empty\n", st);
+       return;
+    }
+    fprintf(f, "%s QUEUE:\n", st);
+    for(pos = 0, d = q.head, p = NULL; d != NULL; p = d, d = d->next, pos++) {
+       if(pos < npr) fprintf(f, "%3d: %-10s %-4s\n",
+                             pos, d->host->hostname, d->name);
+    }
+    if(pos > npr) {
+       if(pos > npr+2) fprintf(f, "  ...\n");
+       if(pos > npr+1) {
+           d = p->prev;
+           fprintf(f, "%3d: %-10s %-4s\n", pos-2, d->host->hostname, d->name);
+       }
+       d = p;
+       fprintf(f, "%3d: %-10s %-4s\n", pos-1, d->host->hostname, d->name);
+    }
+}
+
+char *optionstr(dp, their_features, fdout)
+disk_t *dp;
+am_feature_t * their_features;
+FILE *fdout;
+{
+    char *auth_opt = NULL;
+    char *kencrypt_opt = "";
+    char *compress_opt = "";
+    char *record_opt = "";
+    char *index_opt = "";
+    char *exclude_file = NULL;
+    char *exclude_list = NULL;
+    char *include_file = NULL;
+    char *include_list = NULL;
+    char *excl_opt = "";
+    char *incl_opt = "";
+    char *exc = NULL;
+    char *result = NULL;
+    sle_t *excl;
+    int nb_exclude_file;
+    int nb_include_file;
+
+    /* modification by BIS@BBN 4/25/2003:
+     * The first "if" statement has a number of problems, so I removed the
+     * am_has_feature(dp->host->features, fe_options_auth)
+     * condition and caused the first case to always fail.
+     * 1) If dp->host is a NULL pointer, subsequent tests which look
+     *    at dp->host->features or dp->host->hostname will cause a dump.
+     *    It appears that there should be an assertion that dp->host
+     *    is NOT NULL.
+     * 2) The code which checks for the kencrypt feature is only executed
+     *    in the case where dp->auth == AUTH_KRB4.  If we enable Kerberos IV
+     *    in the first case, then the code checking for kencrypt will never
+     *    be executed.
+     * 3) The option processing code in server-src/dumper.c and
+     *    client-src/sendbackup.c do not yet handle the "auth=krb4"
+     *    option style of specifying Kerberos IV.
+     * Getting rid of the whole first case seems to take care of problems
+     * 2 and 3, but not problem 1.
+     */
+    if(dp->host && 0)
+       /* && am_has_feature(dp->host->features, fe_options_auth)) */ {
+       auth_opt = stralloc("auth=");
+       if(dp->auth == AUTH_BSD) {
+           strappend(auth_opt, "bsd");
+       } else if(dp->auth == AUTH_KRB4) {
+           strappend(auth_opt, "krb4");
+       } else {
+           strappend(auth_opt, "unknown");
+       }
+       strappend(auth_opt, ";");
+    } else if(dp->auth == AUTH_BSD) {
+       if(am_has_feature(dp->host->features, fe_options_bsd_auth)) {
+           auth_opt = stralloc("bsd-auth;");
+       }
+       else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support bsd-auth\n",
+                   dp->host->hostname, dp->name);
+       }
+    } else if(dp->auth == AUTH_KRB4) {
+       if(am_has_feature(dp->host->features, fe_options_krb4_auth)) {
+           auth_opt = stralloc("krb4-auth;");
+       }
+       else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support krb4-auth\n",
+                   dp->host->hostname, dp->name);
+       }
+       if(dp->kencrypt) {
+           if(am_has_feature(dp->host->features, fe_options_kencrypt)) {
+               kencrypt_opt = "kencrypt;";
+           }
+           else if(fdout) {
+               fprintf(fdout,
+                       "WARNING: %s:%s does not support kencrypt\n",
+                       dp->host->hostname, dp->name);
+           }
+       }
+    }
+
+    switch(dp->compress) {
+    case COMP_FAST:
+       if(am_has_feature(their_features, fe_options_compress_fast)) {
+           compress_opt = "compress-fast;";
+       }
+       else if(fdout) {
+           fprintf(fdout,
+                   "WARNING: %s:%s does not support fast compression\n",
+                   dp->host->hostname, dp->name);
+       }
+       break;
+    case COMP_BEST:
+       if(am_has_feature(their_features, fe_options_compress_best)) {
+           compress_opt = "compress-best;";
+       }
+       else if(fdout) {
+           fprintf(fdout,
+                   "WARNING: %s:%s does not support best compression\n",
+                   dp->host->hostname, dp->name);
+       }
+       break;
+    case COMP_SERV_FAST:
+       if(am_has_feature(their_features, fe_options_srvcomp_fast)) {
+           compress_opt = "srvcomp-fast;";
+       }
+       break;
+    case COMP_SERV_BEST:
+       if(am_has_feature(their_features, fe_options_srvcomp_best)) {
+            compress_opt = "srvcomp-best;";
+       }
+       break;
+    }
+
+    if(!dp->record) {
+       if(am_has_feature(their_features, fe_options_no_record)) {
+           record_opt = "no-record;";
+       }
+       else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support no record\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+
+    if(dp->index) {
+       if(am_has_feature(their_features, fe_options_index)) {
+           index_opt = "index;";
+       }
+       else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support index\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+
+    exclude_file = stralloc("");
+    nb_exclude_file = 0;
+    if(dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
+       nb_exclude_file = dp->exclude_file->nb_element;
+       if(am_has_feature(their_features, fe_options_exclude_file)) {
+           if(am_has_feature(their_features, fe_options_multiple_exclude) ||
+              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);
+                   strappend(exclude_file, exc);
+               }
+           } else {
+               exc = newvstralloc(exc, "exclude-file=",
+                                  dp->exclude_file->last->name, ";", NULL);
+               strappend(exclude_file, exc);
+               if(fdout) {
+                   fprintf(fdout,
+                      "WARNING: %s:%s does not support multiple exclude\n",
+                      dp->host->hostname, dp->name);
+               }
+           }
+       } else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support exclude file\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+    exclude_list = stralloc("");
+    if(dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
+       if(am_has_feature(their_features, fe_options_exclude_list)) {
+           if(am_has_feature(their_features, fe_options_multiple_exclude) ||
+              (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);
+                   strappend(exclude_list, exc);
+               }
+           } else {
+               exc = newvstralloc(exc, "exclude-list=",
+                                  dp->exclude_list->last->name, ";", NULL);
+               strappend(exclude_list, exc);
+               if(fdout) {
+                       fprintf(fdout,
+                        "WARNING: %s:%s does not support multiple exclude\n",
+                        dp->host->hostname, dp->name);
+               }
+           }
+       } else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support exclude list\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+
+    include_file = stralloc("");
+    nb_include_file = 0;
+    if(dp->include_file != NULL && dp->include_file->nb_element > 0) {
+       nb_include_file = dp->include_file->nb_element;
+       if(am_has_feature(their_features, fe_options_include_file)) {
+           if(am_has_feature(their_features, fe_options_multiple_include) ||
+              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);
+                   strappend(include_file, exc);
+               }
+           } else {
+               exc = newvstralloc(exc, "include-file=",
+                                  dp->include_file->last->name, ";", NULL);
+               strappend(include_file, exc);
+               if(fdout) {
+                   fprintf(fdout,
+                        "WARNING: %s:%s does not support multiple include\n",
+                        dp->host->hostname, dp->name);
+               }
+           }
+       } else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support include file\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+    include_list = stralloc("");
+    if(dp->include_list != NULL && dp->include_list->nb_element > 0) {
+       if(am_has_feature(their_features, fe_options_include_list)) {
+           if(am_has_feature(their_features, fe_options_multiple_include) ||
+              (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);
+                   strappend(include_list, exc);
+               }
+           } else {
+               exc = newvstralloc(exc, "include-list=",
+                                  dp->include_list->last->name, ";", NULL);
+               strappend(include_list, exc);
+               if(fdout) {
+                       fprintf(fdout,
+                        "WARNING: %s:%s does not support multiple include\n",
+                        dp->host->hostname, dp->name);
+               }
+           }
+       } else if(fdout) {
+           fprintf(fdout, "WARNING: %s:%s does not support include list\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+
+    if(dp->exclude_optional) {
+       if(am_has_feature(their_features, fe_options_optional_exclude)) {
+           excl_opt = "exclude-optional;";
+       }
+       else if(fdout) {
+           fprintf(fdout,
+                   "WARNING: %s:%s does not support optional exclude\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+    if(dp->include_optional) {
+       if(am_has_feature(their_features, fe_options_optional_include)) {
+          incl_opt = "include-optional;";
+       }
+       else if(fdout) {
+           fprintf(fdout,
+                   "WARNING: %s:%s does not support optional include\n",
+                   dp->host->hostname, dp->name);
+       }
+    }
+
+    result = vstralloc(";",
+                      auth_opt,
+                      kencrypt_opt,
+                      compress_opt,
+                      record_opt,
+                      index_opt,
+                      exclude_file,
+                      exclude_list,
+                      include_file,
+                      include_list,
+                      excl_opt,
+                      incl_opt,
+                      NULL);
+    amfree(auth_opt);
+    amfree(exclude_file);
+    amfree(exclude_list);
+    amfree(include_file);
+    amfree(include_list);
+    amfree(exc);
+
+    return result;
+}
+
+void match_disklist(disklist_t *origqp, int sargc, char **sargv)
+{
+    char *prevhost = NULL;
+    int i;
+    int match_a_host;
+    int match_a_disk;
+    int prev_match;
+    disk_t *dp;
+
+    if(sargc <= 0)
+       return;
+
+    for(dp = origqp->head; dp != NULL; dp = dp->next) {
+       if(dp->todo == 1)
+           dp->todo = -1;
+    }
+
+    prev_match = 0;
+    for(i=0;i<sargc;i++) {
+       match_a_host = 0;
+       for(dp = origqp->head; dp != NULL; dp = dp->next) {
+           if(match_host(sargv[i], dp->host->hostname))
+               match_a_host = 1;
+       }
+       match_a_disk = 0;
+       for(dp = origqp->head; dp != NULL; dp = dp->next) {
+           if(prevhost != NULL &&
+              match_host(prevhost, dp->host->hostname) &&
+              (match_disk(sargv[i], dp->name) ||
+               (dp->device && match_disk(sargv[i], dp->device)))) {
+               if(match_a_host) {
+                   error("Argument %s match a host and a disk",sargv[i]);
+               }
+               else {
+                   if(dp->todo == -1) {
+                       dp->todo = 1;
+                       match_a_disk = 1;
+                       prev_match = 0;
+                   }
+               }
+           }
+       }
+       if(!match_a_disk) {
+           if(match_a_host == 1) {
+               if(prev_match == 1) { /* all disk of the previous host */
+                   for(dp = origqp->head; dp != NULL; dp = dp->next) {
+                       if(match_host(prevhost,dp->host->hostname))
+                           if(dp->todo == -1)
+                               dp->todo = 1;
+                   }
+               }
+               prevhost = sargv[i];
+               prev_match = 1;
+           }
+           else {
+               prev_match = 0;
+               /*error("%s match nothing",sargv[i]);*/
+           }
+       }
+    }
+
+    if(prev_match == 1) { /* all disk of the previous host */
+       for(dp = origqp->head; dp != NULL; dp = dp->next) {
+           if(match_host(prevhost,dp->host->hostname))
+               if(dp->todo == -1)
+                   dp->todo = 1;
+       }
+    }
+
+    for(dp = origqp->head; dp != NULL; dp = dp->next) {
+       if(dp->todo == -1)
+           dp->todo = 0;
+    }
+}
+
+#ifdef TEST
+
+void
+dump_disk(dp)
+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,
+          dp->name == NULL? "(null)": dp->name,
+          dp->spindle);
+}
+
+void
+dump_disklist()
+{
+    disk_t *dp, *prev;
+    host_t *hp;
+
+    if(hostlist == NULL) {
+       printf("DISKLIST not read in\n");
+       return;
+    }
+
+    printf("DISKLIST BY HOSTNAME:\n");
+
+    for(hp = hostlist; hp != NULL; hp = hp->next) {
+       printf("HOST %s INTERFACE %s\n",
+              hp->hostname,
+              (hp->netif == NULL||hp->netif->name == NULL) ? "(null)"
+                                                           : hp->netif->name);
+       for(dp = hp->disks; dp != NULL; dp = dp->hostnext)
+           dump_disk(dp);
+       putchar('\n');
+    }
+
+
+    printf("DISKLIST IN FILE ORDER:\n");
+
+    prev = NULL;
+    for(dp = lst.head; dp != NULL; prev = dp, dp = dp->next) {
+       dump_disk(dp);
+       /* check pointers */
+       if(dp->prev != prev) printf("*** prev pointer mismatch!\n");
+       if(dp->next == NULL && lst.tail != dp) printf("tail mismatch!\n");
+    }
+}
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+  char *conffile;
+  char *conf_diskfile;
+  int result;
+  int fd;
+  unsigned long malloc_hist_1, malloc_size_1;
+  unsigned long malloc_hist_2, malloc_size_2;
+
+  for(fd = 3; fd < 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
+     * descriptor, which in turn might be used as an index into
+     * an array (e.g. an fd_set).
+     */
+    close(fd);
+  }
+
+  set_pname("diskfile");
+
+  malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+  if (argc>1) {
+    config_name = argv[1];
+    if (strchr(config_name, '/') != NULL) {
+      config_dir = stralloc2(argv[1], "/");
+      config_name = strrchr(config_name, '/') + 1;
+    } else {
+      config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+    }
+  } else {
+    config_dir = stralloc("");
+  }
+  conffile = stralloc2(config_dir, CONFFILE_NAME);
+  if((result = read_conffile(conffile)) == 0) {
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+      conf_diskfile = stralloc(conf_diskfile);
+    } else {
+      conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((result = (read_diskfile(conf_diskfile) == NULL)) == 0) {
+      dump_disklist();
+    }
+    amfree(conf_diskfile);
+  }
+  amfree(conffile);
+  amfree(config_dir);
+
+  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 */
diff --git a/server-src/diskfile.h b/server-src/diskfile.h
new file mode 100644 (file)
index 0000000..403b569
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: diskfile.h,v 1.11.4.3.4.1.2.9 2003/01/04 03:35:54 martinea Exp $
+ *
+ * interface for disklist file reading code
+ */
+#ifndef DISKFILE_H
+#define DISKFILE_H
+
+#include "amanda.h"
+#include "conffile.h"
+#include "amfeatures.h"
+
+typedef struct host_s {
+    struct host_s *next;               /* next host */
+    char *hostname;                    /* name of host */
+    struct disk_s *disks;              /* linked list of disk records */
+    int inprogress;                    /* # dumps in progress */
+    int maxdumps;                      /* maximum dumps in parallel */
+    interface_t *netif;                        /* network interface this host is on */
+    time_t start_t;                    /* start dump after this time */
+    char *up;                          /* generic user pointer */
+    am_feature_t *features;            /* feature set */
+} host_t;
+
+typedef struct disk_s {
+    int line;                          /* line number of last definition */
+    struct disk_s *prev, *next;                /* doubly linked disk list */
+
+    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 */
+    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 dumpcycle;                    /* days between fulls */
+    long frequency;                    /* XXX - not used */
+    auth_t auth;                       /* type of authentication (per system?) */
+    int maxdumps;                      /* max number of parallel dumps (per system) */
+    int maxpromoteday;                 /* maximum of promote day */
+    time_t start_t;                    /* start this dump after this time */
+    int strategy;                      /* what dump strategy to use */
+    int compress;                      /* type of compression to use */
+    float 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 */
+} disk_t;
+
+typedef struct disklist_s {
+    disk_t *head, *tail;
+} disklist_t;
+
+#define empty(dlist)   ((dlist).head == NULL)
+
+
+disklist_t *read_diskfile P((char *filename));
+
+disk_t *add_disk P((char *hostname, char *diskname));
+host_t *lookup_host P((char *hostname));
+disk_t *lookup_disk P((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 dump_queue P((char *str, disklist_t q, int npr, FILE *f));
+
+char *optionstr P((disk_t *dp, am_feature_t *their_features, FILE *fdout));
+
+void match_disklist P((disklist_t *origqp, int sargc, char **sargv));
+
+#endif /* ! DISKFILE_H */
diff --git a/server-src/driver.c b/server-src/driver.c
new file mode 100644 (file)
index 0000000..1d3bc76
--- /dev/null
@@ -0,0 +1,2342 @@
+/*
+ * 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: driver.c,v 1.58.2.31.2.8.2.21 2004/04/26 15:02:47 martinea Exp $
+ *
+ * controlling process for the Amanda backup system
+ */
+
+/*
+ * XXX possibly modify tape queue to be cognizant of how much room is left on
+ *     tape.  Probably not effective though, should do this in planner.
+ */
+
+#include "amanda.h"
+#include "clock.h"
+#include "conffile.h"
+#include "diskfile.h"
+#include "holding.h"
+#include "infofile.h"
+#include "logfile.h"
+#include "statfs.h"
+#include "version.h"
+#include "driverio.h"
+#include "server_util.h"
+
+disklist_t waitq, runq, tapeq, roomq;
+int pending_aborts, inside_dump_to_tape;
+disk_t *taper_disk;
+int degraded_mode;
+unsigned long reserved_space;
+unsigned long total_disksize;
+char *dumper_program;
+int  inparallel;
+int nodump = 0;
+long tape_length, tape_left = 0;
+int conf_taperalgo;
+host_t *flushhost = NULL;
+
+int client_constrained P((disk_t *dp));
+int sort_by_priority_reversed P((disk_t *a, disk_t *b));
+int sort_by_time P((disk_t *a, disk_t *b));
+int start_some_dumps P((disklist_t *rq));
+void dump_schedule P((disklist_t *qp, char *str));
+void start_degraded_mode P((disklist_t *queuep));
+void handle_taper_result P((void));
+dumper_t *idle_dumper P((void));
+int some_dumps_in_progress P((void));
+int num_busy_dumpers P((void));
+dumper_t *lookup_dumper P((int fd));
+void handle_dumper_result P((int fd));
+void read_flush P((disklist_t *tapeqp));
+void read_schedule P((disklist_t *waitqp, disklist_t *runqp));
+int free_kps P((interface_t *ip));
+void interface_state P((char *time_str));
+void allocate_bandwidth P((interface_t *ip, int kps));
+void deallocate_bandwidth P((interface_t *ip, int kps));
+unsigned long free_space P((void));
+assignedhd_t **find_diskspace P((unsigned long size, int *cur_idle, assignedhd_t *preferred));
+char *diskname2filename P((char *dname));
+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));
+assignedhd_t **build_diskspace P((char *destname));
+void holdingdisk_state P((char *time_str));
+int dump_to_tape P((disk_t *dp));
+int queue_length P((disklist_t q));
+void short_dump_state P((void));
+void dump_state P((char *str));
+void startaflush P((void));
+int main P((int main_argc, char **main_argv));
+
+static int idle_reason;
+char *datestamp;
+
+char *idle_strings[] = {
+#define NOT_IDLE               0
+    "not-idle",
+#define IDLE_START_WAIT                1
+    "start-wait",
+#define IDLE_NO_DUMPERS                2
+    "no-dumpers",
+#define IDLE_NO_HOLD           3
+    "no-hold",
+#define IDLE_CLIENT_CONSTRAINED        4
+    "client-constrained",
+#define IDLE_NO_DISKSPACE      5
+    "no-diskspace",
+#define IDLE_TOO_LARGE         6
+    "file-too-large",
+#define IDLE_NO_BANDWIDTH      7
+    "no-bandwidth",
+#define IDLE_TAPER_WAIT                8
+    "taper-wait",
+};
+
+#define SLEEP_MAX              (24*3600)
+struct timeval sleep_time = { SLEEP_MAX, 0 };
+/* enabled if any disks are in start-wait: */
+int any_delayed_disk = 0;
+
+int main(main_argc, main_argv)
+     int main_argc;
+     char **main_argv;
+{
+    disklist_t *origqp;
+    disk_t *diskp;
+    fd_set selectset;
+    int fd, dsk;
+    dumper_t *dumper;
+    char *newdir = NULL;
+    generic_fs_stats_t fs;
+    holdingdisk_t *hdp;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    unsigned long reserve = 100;
+    char *conffile;
+    char *conf_diskfile;
+    cmd_t cmd;
+    int result_argc;
+    char *result_argv[MAX_ARGS+1];
+    char *taper_program;
+    amwait_t retstat;
+    char *conf_tapetype;
+    tapetype_t *tape;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("driver");
+
+    signal(SIGPIPE, SIG_IGN);
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
+    set_logerror(logerror);
+
+    startclock();
+    FD_ZERO(&readset);
+
+    printf("%s: pid %ld executable %s version %s\n",
+          get_pname(), (long) getpid(), main_argv[0], version());
+
+    if (main_argc > 1) {
+       config_name = stralloc(main_argv[1]);
+       config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+       if(main_argc > 2) {
+           if(strncmp(main_argv[2], "nodump", 6) == 0) {
+               nodump = 1;
+           }
+       }
+
+    } else {
+       char my_cwd[STR_SIZE];
+
+       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+           error("cannot determine current working directory");
+       }
+       config_dir = stralloc2(my_cwd, "/");
+       if ((config_name = strrchr(my_cwd, '/')) != NULL) {
+           config_name = stralloc(config_name + 1);
+       }
+    }
+
+    safe_cd();
+
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if(read_conffile(conffile)) {
+       error("errors processing config file \"%s\"", conffile);
+    }
+    amfree(conffile);
+
+    amfree(datestamp);
+    datestamp = construct_datestamp(NULL);
+    log_add(L_START,"date %s", datestamp);
+
+    taper_program = vstralloc(libexecdir, "/", "taper", versionsuffix(), NULL);
+    dumper_program = vstralloc(libexecdir, "/", "dumper", versionsuffix(),
+                              NULL);
+
+    conf_taperalgo = getconf_int(CNF_TAPERALGO);
+    conf_tapetype = getconf_str(CNF_TAPETYPE);
+    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();
+    startup_tape_process(taper_program);
+    taper_cmd(START_TAPER, datestamp, NULL, 0, NULL);
+
+    /* start initializing: read in databases */
+
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((origqp = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist \"%s\"", conf_diskfile);
+    }
+    amfree(conf_diskfile);
+
+    /* set up any configuration-dependent variables */
+
+    inparallel = getconf_int(CNF_INPARALLEL);
+
+    reserve = getconf_int(CNF_RESERVE);
+
+    total_disksize = 0;
+    for(hdp = getconf_holdingdisks(), dsk = 0; hdp != NULL; hdp = hdp->next, dsk++) {
+       hdp->up = (void *)alloc(sizeof(holdalloc_t));
+       holdalloc(hdp)->allocated_dumpers = 0;
+       holdalloc(hdp)->allocated_space = 0L;
+
+       if(get_fs_stats(hdp->diskdir, &fs) == -1
+          || access(hdp->diskdir, W_OK) == -1) {
+           log_add(L_WARNING, "WARNING: ignoring holding disk %s: %s\n",
+                   hdp->diskdir, strerror(errno));
+           hdp->disksize = 0L;
+           continue;
+       }
+
+       if(fs.avail != -1) {
+           if(hdp->disksize > 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);
+                           hdp->disksize = fs.avail;
+               }
+           }
+           else if(fs.avail + hdp->disksize < 0) {
+               log_add(L_WARNING,
+                       "WARNING: %s: not %ld KB free.",
+                       hdp->diskdir, -hdp->disksize);
+               hdp->disksize = 0L;
+               continue;
+           }
+           else
+               hdp->disksize += fs.avail;
+       }
+
+       printf("driver: adding holding disk %d dir %s size %ld\n",
+              dsk, hdp->diskdir, hdp->disksize);
+
+       newdir = newvstralloc(newdir,
+                             hdp->diskdir, "/", datestamp,
+                             NULL);
+        if(!mkholdingdir(newdir)) {
+           hdp->disksize = 0L;
+       }
+       total_disksize += hdp->disksize;
+    }
+
+    reserved_space = total_disksize * (reserve / 100.0);
+
+    printf("reserving %ld out of %ld for degraded-mode dumps\n",
+               reserved_space, free_space());
+
+    amfree(newdir);
+
+    if(inparallel > MAX_DUMPERS) inparallel = MAX_DUMPERS;
+
+    /* fire up the dumpers now while we are waiting */
+
+    if(!nodump) startup_dump_processes(dumper_program, inparallel);
+
+    /*
+     * Read schedule from stdin.  Usually, this is a pipe from planner,
+     * so the effect is that we wait here for the planner to
+     * finish, but meanwhile the taper is rewinding the tape, reading
+     * the label, checking it, writing a new label and all that jazz
+     * in parallel with the planner.
+     */
+
+    waitq = *origqp;
+    tapeq.head = tapeq.tail = NULL;
+    roomq.head = roomq.tail = NULL;
+    runq.head = runq.tail = NULL;
+
+    read_flush(&tapeq);
+    if(!nodump) read_schedule(&waitq, &runq);
+
+    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(" dir %s datestamp %s driver: drain-ends tapeq %s big-dumpers %s\n",
+          "OBSOLETE", datestamp, taperalgo2str(conf_taperalgo),
+          getconf_str(CNF_DUMPORDER));
+    fflush(stdout);
+
+    /* ok, planner is done, now lets see if the tape is ready */
+
+    cmd = getresult(taper, 1, &result_argc, result_argv, MAX_ARGS+1);
+
+    if(cmd != TAPER_OK) {
+       /* no tape, go into degraded mode: dump to holding disk */
+       start_degraded_mode(&runq);
+       FD_CLR(taper,&readset);
+    }
+
+    tape_left = tape_length;
+    taper_busy = 0;
+    taper_disk = NULL;
+    startaflush();
+
+    while(start_some_dumps(&runq) || some_dumps_in_progress() ||
+         any_delayed_disk) {
+
+       short_dump_state();
+
+       /* wait for results */
+
+       memcpy(&selectset, &readset, sizeof(fd_set));
+       if(select(maxfd+1, (SELECT_ARG_TYPE *)(&selectset),
+                 NULL, NULL, &sleep_time) == -1)
+           error("select: %s", strerror(errno));
+
+       /* handle any results that have come in */
+
+       for(fd = 0; fd <= maxfd; fd++) {
+           /*
+            * The first pass through the following loop, we have
+            * data ready for areads (called by getresult, called by
+            * handle_.*_result).  But that may read more than one record,
+            * so we need to keep processing as long as areads has data.
+            * We will get control back after each record and the buffer
+            * will go empty (indicated by areads_dataready(fd) == 0)
+            * after the last one available has been processed.
+            */
+           while(FD_ISSET(fd, &selectset) || areads_dataready(fd) > 0) {
+               if(fd == taper) handle_taper_result();
+               else handle_dumper_result(fd);
+               FD_CLR(fd, &selectset);
+           }
+       }
+
+    }
+
+    /* handle any remaining dumps by dumping directly to tape, if possible */
+
+    while(!empty(runq)) {
+       diskp = dequeue_disk(&runq);
+       if(!degraded_mode) {
+           int rc = dump_to_tape(diskp);
+           if(rc == 1)
+               log_add(L_INFO,
+                       "%s %s %d [dump to tape failed, will try again]",
+                       diskp->host->hostname,
+                       diskp->name,
+                       sched(diskp)->level);
+           else if(rc == 2)
+               log_add(L_FAIL, "%s %s %s %d [dump to tape failed]",
+                       diskp->host->hostname,
+                       diskp->name,
+                       sched(diskp)->datestamp,
+                       sched(diskp)->level);
+       }
+       else
+           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");
+    }
+
+    short_dump_state();                                /* for amstatus */
+
+    printf("driver: QUITTING time %s telling children to quit\n",
+           walltime_str(curclock()));
+    fflush(stdout);
+
+    if(!nodump) {
+       for(dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
+           dumper_cmd(dumper, QUIT, NULL);
+       }
+    }
+
+    if(taper >= 0) {
+       taper_cmd(QUIT, NULL, NULL, 0, NULL);
+    }
+
+    /* 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) {
+           ap_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);
+    }
+
+    for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
+       cleanup_holdingdisk(hdp->diskdir, 0);
+       amfree(hdp->up);
+    }
+    amfree(newdir);
+
+    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(dumper_program);
+    amfree(taper_program);
+    amfree(config_dir);
+    amfree(config_name);
+
+    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 0;
+}
+
+void startaflush() {
+    disk_t *dp = NULL;
+    disk_t *fit = NULL;
+    char *datestamp;
+
+    if(!degraded_mode && !taper_busy && !empty(tapeq)) {
+       datestamp = sched(tapeq.head)->datestamp;
+       switch(conf_taperalgo) {
+       case ALGO_FIRST:
+               dp = dequeue_disk(&tapeq);
+               break;
+       case ALGO_FIRSTFIT: 
+               fit = tapeq.head;
+               while (fit != NULL) {
+                   if(sched(fit)->act_size <= tape_left &&
+                      strcmp(sched(fit)->datestamp, datestamp) <= 0) {
+                       dp = fit;
+                       fit = NULL;
+                   }
+                   else {
+                       fit = fit->next;
+                   }
+               }
+               if(dp) remove_disk(&tapeq, dp);
+               break;
+       case ALGO_LARGEST: 
+               fit = dp = tapeq.head;
+               while (fit != NULL) {
+                   if(sched(fit)->act_size > sched(dp)->act_size &&
+                      strcmp(sched(fit)->datestamp, datestamp) <= 0) {
+                       dp = fit;
+                   }
+                   fit = fit->next;
+               }
+               if(dp) remove_disk(&tapeq, dp);
+               break;
+       case ALGO_LARGESTFIT: 
+               fit = tapeq.head;
+               while (fit != NULL) {
+                   if(sched(fit)->act_size <= tape_left &&
+                      (!dp || sched(fit)->act_size > sched(dp)->act_size) &&
+                      strcmp(sched(fit)->datestamp, datestamp) <= 0) {
+                       dp = fit;
+                   }
+                   fit = fit->next;
+               }
+               if(dp) remove_disk(&tapeq, dp);
+               break;
+       case ALGO_SMALLEST: 
+               fit = dp = tapeq.head;
+               while (fit != NULL) {
+                   if(sched(fit)->act_size < sched(dp)->act_size &&
+                      strcmp(sched(fit)->datestamp, datestamp) <= 0) {
+                       dp = fit;
+                   }
+                   fit = fit->next;
+               }
+               if(dp) remove_disk(&tapeq, dp);
+               break;
+       case ALGO_LAST:
+               dp = tapeq.tail;
+               remove_disk(&tapeq, dp);
+               break;
+       }
+       if(!dp) {
+           dp = dequeue_disk(&tapeq); /* first if nothing fit */
+           fprintf(stderr,
+                   "driver: startaflush: Using first because nothing fit\n");
+       }
+       taper_disk = dp;
+       taper_busy = 1;
+       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);
+       tape_left -= sched(dp)->act_size;
+    }
+}
+
+
+int client_constrained(dp)
+disk_t *dp;
+{
+    disk_t *dp2;
+
+    /* first, check if host is too busy */
+
+    if(dp->host->inprogress >= dp->host->maxdumps) {
+       return 1;
+    }
+
+    /* next, check conflict with other dumps on same spindle */
+
+    if(dp->spindle == -1) {    /* but spindle -1 never conflicts by def. */
+       return 0;
+    }
+
+    for(dp2 = dp->host->disks; dp2 != NULL; dp2 = dp2->hostnext)
+       if(dp2->inprogress && dp2->spindle == dp->spindle) {
+           return 1;
+       }
+
+    return 0;
+}
+
+int start_some_dumps(rq)
+disklist_t *rq;
+{
+    int total, cur_idle;
+    disk_t *diskp, *diskp_accept;
+    dumper_t *dumper;
+    assignedhd_t **holdp=NULL, **holdp_accept;
+    time_t now = time(NULL);
+
+    total = 0;
+    idle_reason = IDLE_NO_DUMPERS;
+    sleep_time.tv_sec = SLEEP_MAX;
+    sleep_time.tv_usec = 0;
+    any_delayed_disk = 0;
+
+    if(rq->head == NULL) {
+       idle_reason = 0;
+       return 0;
+    }
+
+    /*
+     * A potential problem with starting from the bottom of the dump time
+     * distribution is that a slave host will have both one of the shortest
+     * and one of the longest disks, so starting its shortest disk first will
+     * tie up the host and eliminate its longest disk from consideration the
+     * first pass through.  This could cause a big delay in starting that long
+     * disk, which could drag out the whole night's dumps.
+     *
+     * While starting from the top of the dump time distribution solves the
+     * above problem, this turns out to be a bad idea, because the big dumps
+     * will almost certainly pack the holding disk completely, leaving no
+     * room for even one small dump to start.  This ends up shutting out the
+     * small-end dumpers completely (they stay idle).
+     *
+     * The introduction of multiple simultaneous dumps to one host alleviates
+     * the biggest&smallest dumps problem: both can be started at the
+     * beginning.
+     */
+    for(dumper = dmptable; dumper < dmptable+inparallel; dumper++) {
+       if(dumper->busy || dumper->down) continue;
+       /* found an idle dumper, now find a disk for it */
+       diskp = rq->head;
+       diskp_accept = NULL;
+       holdp_accept = NULL;
+
+       if(idle_reason == IDLE_NO_DUMPERS)
+           idle_reason = NOT_IDLE;
+
+       cur_idle = NOT_IDLE;
+
+       while(diskp) {
+           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);
+               sleep_time.tv_sec = min(diskp->host->start_t - now, 
+                                       sleep_time.tv_sec);
+               any_delayed_disk = 1;
+           }
+           else if(diskp->start_t > now) {
+               cur_idle = max(cur_idle, IDLE_START_WAIT);
+               sleep_time.tv_sec = min(diskp->start_t - now, 
+                                       sleep_time.tv_sec);
+               any_delayed_disk = 1;
+           }
+           else if(diskp->host->netif->curusage > 0 &&
+                   sched(diskp)->est_kps > free_kps(diskp->host->netif))
+               cur_idle = max(cur_idle, IDLE_NO_BANDWIDTH);
+           else if(sched(diskp)->no_space)
+               cur_idle = max(cur_idle, IDLE_NO_DISKSPACE);
+           else if((holdp = 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);
+           } else {
+
+               /* disk fits, dump it */
+               int accept = !diskp_accept;
+               if(!accept) {
+                   char dumptype;
+                   char *dumporder = getconf_str(CNF_DUMPORDER);
+                   if(strlen(dumporder) <= (dumper-dmptable)) {
+                       if(dumper-dmptable < 3)
+                           dumptype = 't';
+                       else
+                           dumptype = 'T';
+                   }
+                   else {
+                       dumptype = dumporder[dumper-dmptable];
+                   }
+                   switch(dumptype) {
+                     case 's': accept = (sched(diskp)->est_size < sched(diskp_accept)->est_size);
+                               break;
+                     case 'S': accept = (sched(diskp)->est_size > sched(diskp_accept)->est_size);
+                               break;
+                     case 't': accept = (sched(diskp)->est_time < sched(diskp_accept)->est_time);
+                               break;
+                     case 'T': accept = (sched(diskp)->est_time > sched(diskp_accept)->est_time);
+                               break;
+                     case 'b': accept = (sched(diskp)->est_kps < sched(diskp_accept)->est_kps);
+                               break;
+                     case 'B': accept = (sched(diskp)->est_kps > sched(diskp_accept)->est_kps);
+                               break;
+                     default:  log_add(L_WARNING, "Unknown dumporder character \'%c\', using 's'.\n",
+                                       dumptype);
+                               accept = (sched(diskp)->est_size < sched(diskp_accept)->est_size);
+                               break;
+                   }
+               }
+               if(accept) {
+                   if( !diskp_accept || !degraded_mode || diskp->priority >= diskp_accept->priority) {
+                       if(holdp_accept) free_assignedhd(holdp_accept);
+                       diskp_accept = diskp;
+                       holdp_accept = holdp;
+                   }
+                   else {
+                       free_assignedhd(holdp);
+                   }
+               }
+               else {
+                   free_assignedhd(holdp);
+               }
+           }
+           diskp = diskp->next;
+       }
+
+       diskp = diskp_accept;
+       holdp = holdp_accept;
+       if(diskp) {
+           cur_idle = NOT_IDLE;
+           sched(diskp)->act_size = 0;
+           allocate_bandwidth(diskp->host->netif, sched(diskp)->est_kps);
+           sched(diskp)->activehd = assign_holdingdisk(holdp, diskp);
+           amfree(holdp);
+           diskp->host->inprogress += 1;       /* host is now busy */
+           diskp->inprogress = 1;
+           sched(diskp)->dumper = dumper;
+           sched(diskp)->timestamp = time((time_t *)0);
+
+           dumper->busy = 1;           /* dumper is now busy */
+           dumper->dp = diskp;         /* link disk to dumper */
+           total++;
+           remove_disk(rq, diskp);             /* take it off the run queue */
+           dumper_cmd(dumper, FILE_DUMP, diskp);
+           diskp->host->start_t = time(NULL) + 15;
+       }
+       idle_reason = max(idle_reason, cur_idle);
+    }
+    return total;
+}
+
+int sort_by_priority_reversed(a, b)
+disk_t *a, *b;
+{
+    if(sched(b)->priority - sched(a)->priority != 0)
+       return sched(b)->priority - sched(a)->priority;
+    else
+       return sort_by_time(a, b);
+}
+
+int sort_by_time(a, b)
+disk_t *a, *b;
+{
+    long diff;
+
+    if ((diff = sched(a)->est_time - sched(b)->est_time) < 0) {
+       return -1;
+    } else if (diff > 0) {
+       return 1;
+    } else {
+       return 0;
+    }
+}
+
+void dump_schedule(qp, str)
+disklist_t *qp;
+char *str;
+{
+    disk_t *dp;
+
+    printf("dump of driver schedule %s:\n--------\n", str);
+
+    for(dp = qp->head; dp != NULL; dp = dp->next) {
+       printf("  %-10.10s %.16s 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);
+    }
+    printf("--------\n");
+}
+
+
+void start_degraded_mode(queuep)
+disklist_t *queuep;
+{
+    disk_t *dp;
+    disklist_t newq;
+    unsigned long est_full_size;
+
+    newq.head = newq.tail = 0;
+
+    dump_schedule(queuep, "before start degraded mode");
+
+    est_full_size = 0;
+    while(!empty(*queuep)) {
+       dp = dequeue_disk(queuep);
+
+       if(sched(dp)->level != 0)
+           /* go ahead and do the disk as-is */
+           insert_disk(&newq, dp, sort_by_priority_reversed);
+       else {
+           if (reserved_space + est_full_size + sched(dp)->est_size
+               <= total_disksize) {
+               insert_disk(&newq, dp, sort_by_priority_reversed);
+               est_full_size += sched(dp)->est_size;
+           }
+           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_time = sched(dp)->degr_time;
+               sched(dp)->est_kps  = sched(dp)->degr_kps;
+               insert_disk(&newq, dp, sort_by_priority_reversed);
+           }
+           else {
+               log_add(L_FAIL, "%s %s %s %d [can't switch to incremental dump]",
+                       dp->host->hostname, dp->name,
+                       sched(dp)->datestamp, sched(dp)->level);
+           }
+       }
+    }
+
+    *queuep = newq;
+    degraded_mode = 1;
+
+    dump_schedule(queuep, "after start degraded mode");
+}
+
+void continue_dumps()
+{
+disk_t *dp, *ndp;
+assignedhd_t **h;
+int active_dumpers=0, busy_dumpers=0, i;
+dumper_t *dumper;
+
+    /* First we try to grant diskspace to some dumps waiting for it. */
+    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++ );
+       /* 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++);
+           assert( dumper < dmptable + inparallel );
+           sched(dp)->activehd = assign_holdingdisk( h, dp );
+           dumper_cmd( dumper, CONTINUE, dp );
+           amfree(h);
+           remove_disk( &roomq, dp );
+       }
+    }
+
+    /* So for some disks there is less holding diskspace available than
+     * was asked for. Possible reasons are
+     * a) diskspace has been allocated for other dumps which are
+     *    still running or already being written to tape
+     * b) all other dumps have been suspended due to lack of diskspace
+     * c) this dump doesn't fit on all the holding disks
+     * Case a) is not a problem. We just wait for the diskspace to
+     * be freed by moving the current disk to a queue.
+     * If case b) occurs, we have a deadlock situation. We select
+     * a dump from the queue to be aborted and abort it. It will
+     * be retried later dumping to disk.
+     * If case c) is detected, the dump is aborted. Next time
+     * it will be dumped directly to tape. Actually, case c is a special
+     * manifestation of case b) where only one dumper is busy.
+     */
+    for( dp=NULL, dumper = dmptable; dumper < dmptable + inparallel; dumper++) {
+       if( dumper->busy ) {
+           busy_dumpers++;
+           if( !find_disk(&roomq, dumper->dp) ) {
+               active_dumpers++;
+           } else if( !dp || sched(dp)->est_size > sched(dumper->dp)->est_size ) {
+               dp = dumper->dp;
+           }
+       }
+    }
+    if( !active_dumpers && busy_dumpers > 0 && 
+        ((!taper_busy && empty(tapeq)) || degraded_mode) &&
+       pending_aborts == 0 ) { /* not case a */
+       if( busy_dumpers == 1 ) { /* case c */
+           sched(dp)->no_space = 1;
+       }
+       /* case b */
+       /* At this time, dp points to the dump with the smallest est_size.
+        * We abort that dump, hopefully not wasting too much time retrying it.
+        */
+       remove_disk( &roomq, dp );
+       dumper_cmd( sched(dp)->dumper, ABORT, NULL );
+       pending_aborts++;
+    }
+}
+
+void handle_taper_result()
+{
+    disk_t *dp;
+    int filenum;
+    cmd_t cmd;
+    int result_argc;
+    char *result_argv[MAX_ARGS+1];
+
+    cmd = getresult(taper, 1, &result_argc, result_argv, MAX_ARGS+1);
+
+    switch(cmd) {
+
+    case DONE: /* DONE <handle> <label> <tape file> <err mess> */
+       if(result_argc != 5) {
+           error("error: [taper DONE result_argc != 5: %d", result_argc);
+       }
+
+       dp = serial2disk(result_argv[2]);
+       free_serial(result_argv[2]);
+
+       filenum = atoi(result_argv[4]);
+       update_info_taper(dp, result_argv[3], filenum, sched(dp)->level);
+
+       delete_diskspace(dp);
+
+       printf("driver: finished-cmd time %s taper wrote %s:%s\n",
+              walltime_str(curclock()), dp->host->hostname, dp->name);
+       fflush(stdout);
+
+       amfree(sched(dp)->dumpdate);
+       amfree(sched(dp)->degr_dumpdate);
+       amfree(sched(dp)->datestamp);
+       amfree(dp->up);
+
+       taper_busy = 0;
+       taper_disk = NULL;
+       startaflush();
+       continue_dumps(); /* continue with those dumps waiting for diskspace */
+       break;
+
+    case TRYAGAIN:  /* TRY-AGAIN <handle> <err mess> */
+       if (result_argc < 2) {
+           error("error [taper TRYAGAIN result_argc < 2: %d]", result_argc);
+       }
+       dp = serial2disk(result_argv[2]);
+       free_serial(result_argv[2]);
+       printf("driver: taper-tryagain time %s disk %s:%s\n",
+              walltime_str(curclock()), dp->host->hostname, dp->name);
+       fflush(stdout);
+
+       /* re-insert into taper queue */
+
+       if(sched(dp)->attempted) {
+           log_add(L_FAIL, "%s %s %d %s [too many taper retries]",
+                   dp->host->hostname, dp->name, sched(dp)->level,
+                   sched(dp)->datestamp);
+       }
+       else {
+           sched(dp)->attempted++;
+           headqueue_disk(&tapeq, dp);
+       }
+
+       tape_left = tape_length;
+
+       /* run next thing from queue */
+       taper_busy = 0;
+       taper_disk = NULL;
+       startaflush();
+       continue_dumps(); /* continue with those dumps waiting for diskspace */
+
+       break;
+
+    case TAPE_ERROR: /* TAPE-ERROR <handle> <err mess> */
+       dp = serial2disk(result_argv[2]);
+       free_serial(result_argv[2]);
+       printf("driver: finished-cmd time %s taper wrote %s:%s\n",
+              walltime_str(curclock()), dp->host->hostname, dp->name);
+       fflush(stdout);
+       /* Note: fall through code... */
+
+    case BOGUS:
+       /*
+        * Since we've gotten a tape 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
+        * checks. If there are dumps waiting for diskspace to be freed,
+        * cancel one.
+        */
+       if(!nodump) {
+           log_add(L_WARNING,
+                   "going into degraded mode because of tape error.");
+       }
+       start_degraded_mode(&runq);
+       taper_busy = 0;
+       taper_disk = NULL;
+       tapeq.head = tapeq.tail = NULL;
+       FD_CLR(taper,&readset);
+       if(cmd != TAPE_ERROR) aclose(taper);
+       continue_dumps();
+       break;
+    default:
+       error("driver received unexpected token (%d) from taper", cmd);
+    }
+}
+
+
+dumper_t *idle_dumper()
+{
+    dumper_t *dumper;
+
+    for(dumper = dmptable; dumper < dmptable+inparallel; dumper++)
+       if(!dumper->busy && !dumper->down) return dumper;
+
+    return NULL;
+}
+
+int some_dumps_in_progress()
+{
+    dumper_t *dumper;
+
+    for(dumper = dmptable; dumper < dmptable+inparallel; dumper++)
+       if(dumper->busy) return 1;
+
+    return taper_busy;
+}
+
+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;
+}
+
+dumper_t *lookup_dumper(fd)
+int fd;
+{
+    dumper_t *dumper;
+
+    for(dumper = dmptable; dumper < dmptable+inparallel; dumper++)
+       if(dumper->outfd == fd) return dumper;
+
+    return NULL;
+}
+
+
+void handle_dumper_result(fd)
+     int fd;
+{
+    assignedhd_t **h=NULL;
+    dumper_t *dumper;
+    disk_t *dp, *sdp;
+    long origsize;
+    long dumpsize;
+    long dumptime;
+    cmd_t cmd;
+    int result_argc;
+    char *result_argv[MAX_ARGS+1];
+    int i, dummy;
+    int activehd = -1;
+
+    dumper = lookup_dumper(fd);
+    dp = dumper->dp;
+    assert(dp && sched(dp) && sched(dp)->destname);
+
+    if(dp && sched(dp) && sched(dp)->holdp) {
+       h = sched(dp)->holdp;
+       activehd = sched(dp)->activehd;
+    }
+
+    cmd = getresult(fd, 1, &result_argc, result_argv, MAX_ARGS+1);
+
+    if(cmd != BOGUS) {
+       sdp = serial2disk(result_argv[2]); /* result_argv[2] always contains the serial number */
+       assert(sdp == dp);
+    }
+
+    switch(cmd) {
+
+    case DONE: /* DONE <handle> <origsize> <dumpsize> <dumptime> <err str> */
+       if(result_argc != 6) {
+           error("error [dumper DONE result_argc != 6: %d]", result_argc);
+       }
+
+       free_serial(result_argv[2]);
+
+       origsize = (long)atof(result_argv[3]);
+       dumpsize = (long)atof(result_argv[4]);
+       dumptime = (long)atof(result_argv[5]);
+       update_info_dumper(dp, origsize, dumpsize, dumptime);
+
+       /* adjust holdp[active]->used using the real dumpsize and all other
+        * holdp[i]->used as an estimate.
+        */
+
+       dummy = 0;
+       for( i = 0, h = sched(dp)->holdp; i < activehd; i++ ) {
+           dummy += h[i]->used;
+       }
+
+       rename_tmp_holding(sched(dp)->destname, 1);
+       assert( h && activehd >= 0 );
+       h[activehd]->used = size_holding_files(sched(dp)->destname) - dummy;
+       deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+       holdalloc(h[activehd]->disk)->allocated_dumpers--;
+       adjust_diskspace(dp, DONE);
+       dumper->busy = 0;
+       dp->host->inprogress -= 1;
+       dp->inprogress = 0;
+       sched(dp)->attempted = 0;
+       printf("driver: finished-cmd time %s %s dumped %s:%s\n",
+              walltime_str(curclock()), dumper->name,
+              dp->host->hostname, dp->name);
+       fflush(stdout);
+
+       enqueue_disk(&tapeq, dp);
+       dp = NULL;
+
+       startaflush();
+       continue_dumps();
+
+       break;
+
+    case TRYAGAIN: /* TRY-AGAIN <handle> <err str> */
+    case FATAL_TRYAGAIN:
+       free_serial(result_argv[2]);
+
+       rename_tmp_holding(sched(dp)->destname, 0);
+       deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+       assert( h && activehd >= 0 );
+       holdalloc(h[activehd]->disk)->allocated_dumpers--;
+       /* Because we don't know how much was written to disk the
+        * following functions *must* be called together!
+        */
+       adjust_diskspace(dp, DONE);
+       delete_diskspace(dp);
+       dumper->busy = 0;
+       dp->host->inprogress -= 1;
+       dp->inprogress = 0;
+
+       if(sched(dp)->attempted) {
+           log_add(L_FAIL, "%s %s %d %s[could not connect to %s]",
+                   dp->host->hostname, dp->name,
+                   sched(dp)->level, sched(dp)->datestamp, dp->host->hostname);
+       } else {
+           sched(dp)->attempted++;
+           enqueue_disk(&runq, dp);
+       }
+       continue_dumps();
+
+       if(cmd == FATAL_TRYAGAIN) {
+           /* dumper is confused, start another */
+           log_add(L_WARNING, "%s (pid %ld) confused, restarting it.",
+                   dumper->name, (long)dumper->pid);
+           FD_CLR(fd,&readset);
+           aclose(fd);
+           startup_dump_process(dumper, dumper_program);
+       }
+       /* sleep in case the dumper failed because of a temporary network
+          problem, as NIS or NFS... */
+       sleep(15);
+       break;
+
+    case FAILED: /* FAILED <handle> <errstr> */
+       free_serial(result_argv[2]);
+
+       rename_tmp_holding(sched(dp)->destname, 0);
+       deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+       assert( h && activehd >= 0 );
+       holdalloc(h[activehd]->disk)->allocated_dumpers--;
+       /* Because we don't know how much was written to disk the
+        * following functions *must* be called together!
+        */
+       adjust_diskspace(dp, DONE);
+       delete_diskspace(dp);
+       dumper->busy = 0;
+       dp->host->inprogress -= 1;
+       dp->inprogress = 0;
+       continue_dumps();
+
+       /* no need to log this, dumper will do it */
+       /* sleep in case the dumper failed because of a temporary network
+          problem, as NIS or NFS... */
+       sleep(15);
+       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]);
+       break;
+
+    case RQ_MORE_DISK: /* RQ-MORE-DISK <handle> */
+       assert( h && activehd >= 0 );
+       holdalloc(h[activehd]->disk)->allocated_dumpers--;
+       h[activehd]->used = h[activehd]->reserved;
+       if( h[++activehd] ) { /* There's still some allocated space left. Tell
+                              * the dumper about it. */
+           sched(dp)->activehd++;
+           dumper_cmd( dumper, 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 * 21 / 20; /* +5% */
+           sched(dp)->est_size = am_round(sched(dp)->est_size, DISK_BLOCK_KB);
+           h = find_diskspace( sched(dp)->est_size - sched(dp)->act_size,
+                               &dummy,
+                               h[activehd-1] );
+           if( !h ) {
+    /*     cur_idle = max(cur_idle, IDLE_NO_DISKSPACE); */
+               /* No diskspace available. The reason for this will be
+                * determined in continue_dumps(). */
+               enqueue_disk( &roomq, dp );
+               continue_dumps();
+           } else {
+               /* OK, allocate space for disk and have dumper continue */
+               sched(dp)->activehd = assign_holdingdisk( h, dp );
+               dumper_cmd( dumper, CONTINUE, dp );
+               amfree(h);
+           }
+       }
+       break;
+
+    case ABORT_FINISHED: /* ABORT-FINISHED <handle> */
+       assert(pending_aborts);
+       free_serial(result_argv[2]);
+
+       rename_tmp_holding(sched(dp)->destname, 0);
+       deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+       /* Because we don't know how much was written to disk the
+        * following functions *must* be called together!
+        */
+       adjust_diskspace(dp, DONE);
+       delete_diskspace(dp);
+       sched(dp)->attempted++;
+       enqueue_disk(&runq, dp);        /* we'll try again later */
+       dumper->busy = 0;
+       dp->host->inprogress -= 1;
+       dp->inprogress = 0;
+       dp = NULL;
+       pending_aborts--;
+       continue_dumps();
+       break;
+
+    case BOGUS:
+       /* 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);
+       FD_CLR(fd,&readset);
+       aclose(fd);
+       dumper->busy = 0;
+       dumper->down = 1;       /* mark it down so it isn't used again */
+       if(dp) {
+           /* if it was dumping something, zap it and try again */
+           rename_tmp_holding(sched(dp)->destname, 0);
+           deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+           assert( h && activehd >= 0 );
+           holdalloc(h[activehd]->disk)->allocated_dumpers--;
+           /* Because we don't know how much was written to disk the
+            * following functions *must* be called together!
+            */
+           adjust_diskspace(dp, DONE);
+           delete_diskspace(dp);
+           dp->host->inprogress -= 1;
+           dp->inprogress = 0;
+           if(sched(dp)->attempted) {
+               log_add(L_FAIL, "%s %s %d %s [%s died]",
+                       dp->host->hostname, dp->name,
+                       sched(dp)->level, sched(dp)->datestamp, dumper->name);
+           }
+           else {
+               log_add(L_WARNING, "%s died while dumping %s:%s lev %d.",
+                       dumper->name, dp->host->hostname, dp->name,
+                       sched(dp)->level);
+               sched(dp)->attempted++;
+               enqueue_disk(&runq, dp);
+           }
+           dp = NULL;
+           continue_dumps();
+       }
+       break;
+
+    default:
+       assert(0);
+    }
+
+    return;
+}
+
+
+void read_flush(tapeqp)
+disklist_t *tapeqp;
+{
+    sched_t *sp;
+    disk_t *dp;
+    int line;
+    dumpfile_t file;
+    char *hostname, *diskname, *datestamp;
+    int level;
+    char *destname;
+    disk_t *dp1;
+    char *inpline = NULL;
+    char *command;
+    char *s;
+    int ch;
+    long flush_size = 0;
+
+    /* read schedule from stdin */
+
+    for(line = 0; (inpline = agets(stdin)) != NULL; free(inpline)) {
+       line++;
+
+       s = inpline;
+       ch = *s++;
+
+       skip_whitespace(s, ch);                 /* find the command */
+       if(ch == '\0') {
+           error("Aflush line %d: syntax error", line);
+           continue;
+       }
+       command = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       if(strcmp(command,"ENDFLUSH") == 0) {
+           break;
+       }
+
+       if(strcmp(command,"FLUSH") != 0) {
+           error("Bflush line %d: syntax error", line);
+           continue;
+       }
+
+       skip_whitespace(s, ch);                 /* find the hostname */
+       if(ch == '\0') {
+           error("Cflush line %d: syntax error", line);
+           continue;
+       }
+       hostname = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the diskname */
+       if(ch == '\0') {
+           error("Cflush line %d: syntax error", line);
+           continue;
+       }
+       diskname = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the datestamp */
+       if(ch == '\0') {
+           error("Cflush line %d: syntax error", line);
+           continue;
+       }
+       datestamp = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the level number */
+       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           error("Cflush line %d: syntax error", line);
+           continue;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);                 /* find the filename */
+       if(ch == '\0') {
+           error("Cflush line %d: syntax error", line);
+           continue;
+       }
+       destname = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       get_dumpfile(destname, &file);
+       if( file.type != F_DUMPFILE) {
+           if( file.type != F_CONT_DUMPFILE )
+               log_add(L_INFO, "%s: ignoring cruft file.", destname);
+           continue;
+       }
+
+       if(strcmp(hostname, file.name) != 0 ||
+          strcmp(diskname, file.disk) != 0 ||
+          strcmp(datestamp, file.datestamp) != 0) {
+           log_add(L_INFO, "disk %s:%s not consistent with file %s",
+                   hostname, diskname, destname);
+           continue;
+       }
+
+       dp = lookup_disk(file.name, file.disk);
+
+       if (dp == NULL) {
+           log_add(L_INFO, "%s: disk %s:%s not in database, skipping it.",
+                   destname, file.name, file.disk);
+           continue;
+       }
+
+       if(file.dumplevel < 0 || file.dumplevel > 9) {
+           log_add(L_INFO, "%s: ignoring file with bogus dump level %d.",
+                   destname, file.dumplevel);
+           continue;
+       }
+
+       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(host_t));
+           flushhost->next = NULL;
+           flushhost->hostname = stralloc("FLUSHHOST");
+           flushhost->up = NULL;
+           flushhost->features = NULL;
+       }
+       dp1->hostnext = flushhost->disks;
+       flushhost->disks = dp1;
+
+       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_time = 0;
+       sp->priority = 0;
+       sp->degr_level = -1;
+       sp->est_kps = 10;
+       sp->attempted = 0;
+       sp->act_size = size_holding_files(destname);
+       /*sp->holdp = NULL; JLM: must be build*/
+       sp->holdp = build_diskspace(destname);
+        if(sp->holdp == NULL) continue;
+       sp->dumper = NULL;
+       sp->timestamp = (time_t)0;
+
+       dp1->up = (char *)sp;
+
+       enqueue_disk(tapeqp, dp1);
+       flush_size += sp->act_size;
+    }
+    printf("driver: flush size %ld\n", flush_size);
+    amfree(inpline);
+}
+
+
+void read_schedule(waitqp, runqp)
+disklist_t *waitqp, *runqp;
+{
+    sched_t *sp;
+    disk_t *dp;
+    int level, line, priority;
+    char *dumpdate, *degr_dumpdate;
+    int degr_level;
+    long time, degr_time;
+    unsigned long size, degr_size;
+    char *hostname, *features, *diskname, *datestamp, *inpline = NULL;
+    char *command;
+    char *s;
+    int ch;
+
+    /* read schedule from stdin */
+
+    for(line = 0; (inpline = agets(stdin)) != NULL; free(inpline)) {
+       line++;
+
+       s = inpline;
+       ch = *s++;
+
+       skip_whitespace(s, ch);                 /* find the command */
+       if(ch == '\0') {
+           error("schedule line %d: syntax error (no command)", line);
+           continue;
+       }
+       command = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       if(strcmp(command,"DUMP") != 0) {
+           error("schedule line %d: syntax error (%s != DUMP)", line, command);
+           continue;
+       }
+
+       skip_whitespace(s, ch);                 /* find the host name */
+       if(ch == '\0') {
+           error("schedule line %d: syntax error (no host name)", line);
+           continue;
+       }
+       hostname = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the feature list */
+       if(ch == '\0') {
+           error("schedule line %d: syntax error (no feature list)", line);
+           continue;
+       }
+       features = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the disk name */
+       if(ch == '\0') {
+           error("schedule line %d: syntax error (no disk name)", line);
+           continue;
+       }
+       diskname = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       skip_whitespace(s, ch);                 /* find the datestamp */
+       if(ch == '\0') {
+           error("schedule line %d: syntax error (no datestamp)", line);
+           continue;
+       }
+       datestamp = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       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;
+       }
+       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;
+       }
+       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;
+       }
+       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_integer(s, ch);
+
+       skip_whitespace(s, ch);                 /* find the time number */
+       if(ch == '\0' || sscanf(s - 1, "%ld", &time) != 1) {
+           error("schedule line %d: syntax error (bad estimated time)", line);
+           continue;
+       }
+       skip_integer(s, ch);
+
+       degr_dumpdate = NULL;                   /* flag if degr fields found */
+       skip_whitespace(s, ch);                 /* find the degr level number */
+       if(ch != '\0') {
+           if(sscanf(s - 1, "%d", &degr_level) != 1) {
+               error("schedule line %d: syntax error (bad degr level)", line);
+               continue;
+           }
+           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;
+           }
+           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_integer(s, ch);
+
+           skip_whitespace(s, ch);             /* find the degr time number */
+           if(ch == '\0' || sscanf(s - 1, "%lu", &degr_time) != 1) {
+               error("schedule line %d: syntax error (bad degr estimated time)", line);
+               continue;
+           }
+           skip_integer(s, ch);
+       }
+
+       dp = lookup_disk(hostname, diskname);
+       if(dp == NULL) {
+           log_add(L_WARNING,
+                   "schedule line %d: %s:%s not in disklist, ignored",
+                   line, hostname, diskname);
+           continue;
+       }
+
+       sp = (sched_t *) alloc(sizeof(sched_t));
+       sp->level    = level;
+       sp->dumpdate = stralloc(dumpdate);
+       sp->est_size = DISK_BLOCK_KB + size; /* include header */
+       sp->est_time = time;
+       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_time = degr_time;
+       } 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;
+       }
+
+       sp->attempted = 0;
+       sp->act_size = 0;
+       sp->holdp = NULL;
+       sp->activehd = -1;
+       sp->dumper = NULL;
+       sp->timestamp = (time_t)0;
+       sp->destname = NULL;
+       sp->no_space = 0;
+
+       dp->up = (char *) sp;
+       if(dp->host->features == NULL) {
+           dp->host->features = am_string_to_feature(features);
+       }
+       remove_disk(waitqp, dp);
+       insert_disk(&runq, dp, sort_by_time);
+    }
+    amfree(inpline);
+    if(line == 0)
+       log_add(L_WARNING, "WARNING: got empty schedule from planner");
+}
+
+int free_kps(ip)
+interface_t *ip;
+{
+    int res;
+
+    if (ip == (interface_t *)0) {
+       interface_t *p;
+       int maxusage=0;
+       int curusage=0;
+       for(p = lookup_interface(NULL); p != NULL; p = p->next) {
+           maxusage += p->maxusage;
+           curusage += p->curusage;
+       }
+       res = maxusage - curusage;
+    }
+    else {
+       res = ip->maxusage - ip->curusage;
+    }
+
+    return res;
+}
+
+void interface_state(time_str)
+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("\n");
+}
+
+void allocate_bandwidth(ip, kps)
+interface_t *ip;
+int kps;
+{
+    ip->curusage += kps;
+}
+
+void deallocate_bandwidth(ip, kps)
+interface_t *ip;
+int kps;
+{
+    assert(kps <= ip->curusage);
+    ip->curusage -= kps;
+}
+
+/* ------------ */
+unsigned long free_space()
+{
+    holdingdisk_t *hdp;
+    unsigned long total_free;
+    long diff;
+
+    total_free = 0L;
+    for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
+       diff = hdp->disksize - holdalloc(hdp)->allocated_space;
+       if(diff > 0)
+           total_free += diff;
+    }
+    return total_free;
+}
+
+assignedhd_t **find_diskspace(size, cur_idle, pref)
+unsigned long size;
+int *cur_idle;
+assignedhd_t *pref;
+/* Rewrite by Peter Conrad <conrad@opus5.de>, June '99:
+ *  - enable splitting a dump across several holding disks
+ *  - allocate only as much as size tells us, dumpers may request more later
+ * 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
+ * will allocate the given amount of space.
+ * If there is not enough room on the holdingdisks, NULL is returned.
+ */
+{
+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;
+
+    size = am_round(size, DISK_BLOCK_KB);
+
+#ifdef HOLD_DEBUG
+    printf("find diskspace: want %lu K\n", size );
+    fflush(stdout);
+#endif
+
+    for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
+       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) );
+    result[0] = NULL;
+
+    while( i < num_holdingdisks && size > 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) {
+               minp = hdp;
+               minj = j;
+               break;
+           }
+           else if( holdalloc(hdp)->allocated_space <= hdp->disksize - 2*DISK_BLOCK_KB &&
+               !used[j] && 
+               (!minp ||
+                holdalloc(hdp)->allocated_dumpers < holdalloc(minp)->allocated_dumpers ||
+                (holdalloc(hdp)->allocated_dumpers == holdalloc(minp)->allocated_dumpers &&
+                 hdp->disksize-holdalloc(hdp)->allocated_space > minp->disksize-holdalloc(minp)->allocated_space)) ) {
+               minp = hdp;
+               minj = j;
+           }
+       }
+       pref = NULL;
+       if( !minp ) { break; } /* all holding disks are full */
+       used[minj] = 1;
+
+       /* hfree = free space on the disk */
+       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;
+
+       /* 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;
+
+#ifdef HOLD_DEBUG
+       fprintf(stdout,"find diskspace: size %ld hf %ld df %ld da %ld ha %ld\n",                size, hfree, dfree, dalloc, halloc);
+       fflush(stdout);
+#endif
+       size -= dalloc;
+       result[i] = alloc(sizeof(assignedhd_t));
+       result[i]->disk = minp;
+       result[i]->reserved = halloc;
+       result[i]->used = 0;
+       result[i]->destname = NULL;
+       result[i+1] = NULL;
+       i++;
+    } /* while i < num_holdingdisks && size > 0 */
+    amfree(used);
+
+    if( size ) { /* not enough space available */
+#ifdef HOLD_DEBUG
+       printf("find diskspace: not enough diskspace. Left with %lu K\n", size);
+       fflush(stdout);
+#endif
+       free_assignedhd(result);
+       result = NULL;
+    }
+
+#ifdef HOLD_DEBUG
+    for( i = 0; result && result[i]; i++ ) {
+    printf("find diskspace: selected %s free %ld reserved %ld dumpers %d\n",
+           result[i]->disk->diskdir,
+           result[i]->disk->disksize - holdalloc(result[i]->disk)->allocated_space,
+          result[i]->reserved,
+           holdalloc(result[i]->disk)->allocated_dumpers);
+    }
+    fflush(stdout);
+#endif
+
+    return result;
+}
+
+int assign_holdingdisk(holdp, diskp)
+assignedhd_t **holdp;
+disk_t *diskp;
+{
+/* Modified by Peter Conrad <conrad@opus5.de>, June '99
+ * Modifications for splitting dumps across holding disks:
+ * sched(diskp)->holdp now contains an array of pointers to assignedhd_t.
+ */
+    int i, j, c, l=0;
+    unsigned long size;
+    char *sfn = sanitise_filename(diskp->name);
+    char lvl[64];
+    assignedhd_t **new_holdp;
+
+    ap_snprintf( lvl, sizeof(lvl), "%d", sched(diskp)->level );
+
+    size = am_round(sched(diskp)->est_size - sched(diskp)->act_size,
+                   DISK_BLOCK_KB);
+
+    for( c = 0; holdp[c]; 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));
+    if (sched(diskp)->holdp) {
+       memcpy(new_holdp, sched(diskp)->holdp, j * sizeof(*new_holdp));
+       amfree(sched(diskp)->holdp);
+    }
+    sched(diskp)->holdp = new_holdp;
+    new_holdp = NULL;
+
+    i = 0;
+    if( j > 0 ) { /* This is a request for additional diskspace. See if we can
+                  * merge assignedhd_t's */
+       l=j;
+       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;
+#ifdef HOLD_DEBUG
+           printf("merging holding disk %s to disk %s:%s, add %lu for reserved %lu, left %lu\n",
+                  sched(diskp)->holdp[j-1]->disk->diskdir,
+                  diskp->host->hostname, diskp->name,
+                  holdp[0]->reserved, sched(diskp)->holdp[j-1]->reserved,
+                  size );
+           fflush(stdout);
+#endif
+           i++;
+           amfree(holdp[0]);
+           l=j-1;
+       }
+    }
+
+    /* copy assignedhd_s to sched(diskp), adjust allocated_space */
+    for( ; holdp[i]; i++ ) {
+       holdp[i]->destname = newvstralloc( holdp[i]->destname,
+                                          holdp[i]->disk->diskdir, "/",
+                                          datestamp, "/",
+                                          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;
+#ifdef HOLD_DEBUG
+        printf("assigning holding disk %s to disk %s:%s, reserved %lu, left %lu\n",
+                holdp[i]->disk->diskdir, diskp->host->hostname, diskp->name,
+                holdp[i]->reserved, size );
+        fflush(stdout);
+#endif
+       holdp[i] = NULL; /* so it doesn't get free()d... */
+    }
+    sched(diskp)->holdp[j] = NULL;
+    sched(diskp)->destname = newstralloc(sched(diskp)->destname,sched(diskp)->holdp[0]->destname);
+    amfree(sfn);
+
+    return l;
+}
+
+static void adjust_diskspace(diskp, cmd)
+disk_t *diskp;
+cmd_t cmd;
+{
+/* Re-write by Peter Conrad <conrad@opus5.de>, March '99
+ * Modifications for splitting dumps across holding disks:
+ * Dumpers no longer write more than they've allocated, therefore an
+ * adjustment may only free some allocated space.
+ * 08/99: Jean-Louis suggested that dumpers tell us how much they've written.
+ * We just believe them and don't stat all the files but rely on the used
+ * field.
+ */
+
+    assignedhd_t **holdp;
+    unsigned long total=0;
+    long diff;
+    int i;
+
+#ifdef HOLD_DEBUG
+    printf("adjust: %s:%s %s\n", diskp->host->hostname, diskp->name,
+           sched(diskp)->destname );
+    fflush(stdout);
+#endif
+
+    holdp = sched(diskp)->holdp;
+
+    assert(holdp);
+
+    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;
+#ifdef HOLD_DEBUG
+       printf("adjust: hdisk %s done, reserved %ld used %ld diff %ld alloc %ld dumpers %d\n",
+               holdp[i]->disk->name, holdp[i]->reserved, holdp[i]->used, diff,
+               holdalloc(holdp[i]->disk)->allocated_space,
+               holdalloc(holdp[i]->disk)->allocated_dumpers );
+               fflush(stdout);
+#endif
+       holdp[i]->reserved += diff;
+    }
+
+    sched(diskp)->act_size = total;
+#ifdef HOLD_DEBUG
+    printf("adjust: after: disk %s:%s used %ld\n", diskp->host->hostname,
+          diskp->name, sched(diskp)->act_size );
+    fflush(stdout);
+#endif
+}
+
+static void delete_diskspace(diskp)
+disk_t *diskp;
+{
+/* Re-write by Peter Conrad <conrad@opus5.de>, March '99
+ * Modifications for splitting dumps across holding disks:
+ * After implementing Jean-Louis' suggestion (see above) this looks much
+ * simpler... again, we rely on assignedhd_s containing correct info
+ */
+    assignedhd_t **holdp;
+    int i;
+
+    holdp = sched(diskp)->holdp;
+
+    assert(holdp);
+
+    for( i = 0; holdp[i]; i++ ) { /* for each disk */
+        /* find all files of this dump on that disk, and subtract their
+         * reserved sizes from the disk's allocated space
+         */
+       holdalloc(holdp[i]->disk)->allocated_space -= holdp[i]->used;
+    }
+
+    unlink_holding_files(holdp[0]->destname); /* no need for the entire list, 
+                                                        because unlink_holding_files
+                                                will walk through all files
+                                                        using cont_filename */
+
+    free_assignedhd(sched(diskp)->holdp);
+    sched(diskp)->holdp = NULL;
+    sched(diskp)->act_size = 0;
+    amfree(sched(diskp)->destname);
+}
+
+assignedhd_t **build_diskspace(destname)
+char *destname;
+{
+    int i, j;
+    int fd;
+    int buflen;
+    char buffer[DISK_BLOCK_BYTES];
+    dumpfile_t file;
+    assignedhd_t **result;
+    holdingdisk_t *hdp;
+    int *used;
+    int num_holdingdisks=0;
+    char dirname[1000], *ch;
+    struct stat finfo;
+    char *filename = destname;
+
+    for(hdp = getconf_holdingdisks(); hdp != NULL; hdp = hdp->next) {
+        num_holdingdisks++;
+    }
+    used = alloc(sizeof(int) * num_holdingdisks);
+    for(i=0;i<num_holdingdisks;i++)
+       used[i] = 0;
+    result = alloc( sizeof(assignedhd_t *) * (num_holdingdisks+1) );
+    result[0] = NULL;
+    while(filename != NULL && filename[0] != '\0') {
+       strncpy(dirname, filename, 999);
+       dirname[999]='\0';
+       ch = strrchr(dirname,'/');
+        *ch = '\0';
+       ch = strrchr(dirname,'/');
+        *ch = '\0';
+
+       for(j = 0, hdp = getconf_holdingdisks(); hdp != NULL;
+                                                hdp = hdp->next, j++ ) {
+           if(strcmp(dirname,hdp->diskdir)==0) {
+               break;
+           }
+       }
+
+       if(stat(filename, &finfo) == -1) {
+           fprintf(stderr, "stat %s: %s\n", filename, strerror(errno));
+           finfo.st_size = 0;
+       }
+       used[j] += (finfo.st_size+1023)/1024;
+       if((fd = open(filename,O_RDONLY)) == -1) {
+           fprintf(stderr,"build_diskspace: open of %s failed: %s\n",
+                   filename, strerror(errno));
+           return NULL;
+       }
+       buflen = fullread(fd, buffer, sizeof(buffer));
+       parse_file_header(buffer, &file, buflen);
+       close(fd);
+       filename = file.cont_filename;
+    }
+
+    for(j = 0, i=0, hdp = getconf_holdingdisks(); hdp != NULL;
+                                                 hdp = hdp->next, j++ ) {
+       if(used[j]) {
+           result[i] = alloc(sizeof(assignedhd_t));
+           result[i]->disk = hdp;
+           result[i]->reserved = used[j];
+           result[i]->used = used[j];
+           result[i]->destname = stralloc(destname);
+           result[i+1] = NULL;
+           i++;
+       }
+    }
+
+    amfree(used);
+    return result;
+}
+
+
+void holdingdisk_state(time_str)
+char *time_str;
+{
+    holdingdisk_t *hdp;
+    int dsk;
+    long 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("\n");
+}
+
+static void update_failed_dump_to_tape(dp)
+disk_t *dp;
+{
+    time_t save_timestamp = sched(dp)->timestamp;
+    /* setting timestamp to 0 removes the current level from the
+     * database, so that we ensure that it will not be bumped to the
+     * next level on the next run.  If we didn't do this, dumpdates or
+     * 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);
+    sched(dp)->timestamp = save_timestamp;
+}
+
+/* ------------------- */
+int dump_to_tape(dp)
+     disk_t *dp;
+{
+    dumper_t *dumper;
+    int failed = 0;
+    int filenum;
+    long origsize = 0;
+    long dumpsize = 0;
+    long dumptime = 0;
+    cmd_t cmd;
+    int result_argc;
+    char *result_argv[MAX_ARGS+1];
+
+    inside_dump_to_tape = 1;   /* for simulator */
+
+    printf("driver: dumping %s:%s directly to tape\n",
+          dp->host->hostname, dp->name);
+    fflush(stdout);
+
+    /* pick a dumper and fail if there are no idle dumpers */
+
+    dumper = idle_dumper();
+    if (!dumper) {
+       printf("driver: no idle dumpers for %s:%s.\n", 
+               dp->host->hostname, dp->name);
+       fflush(stdout);
+       log_add(L_WARNING, "no idle dumpers for %s:%s.\n",
+               dp->host->hostname, dp->name);
+       inside_dump_to_tape = 0;
+       return 2;       /* fatal problem */
+    }
+
+    /* tell the taper to read from a port number of its choice */
+
+    taper_cmd(PORT_WRITE, dp, NULL, sched(dp)->level, sched(dp)->datestamp);
+    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);
+       fflush(stdout);
+       inside_dump_to_tape = 0;
+       return 2;       /* fatal problem */
+    }
+    /* copy port number */
+    sched(dp)->destname = newvstralloc(sched(dp)->destname, result_argv[2], NULL );
+
+    /* tell the dumper to dump to a port */
+
+    dumper_cmd(dumper, PORT_DUMP, dp);
+    dp->host->start_t = time(NULL) + 15;
+
+    /* update statistics & print state */
+
+    taper_busy = dumper->busy = 1;
+    dp->host->inprogress += 1;
+    dp->inprogress = 1;
+    sched(dp)->timestamp = time((time_t *)0);
+    allocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+    idle_reason = 0;
+
+    short_dump_state();
+
+    /* wait for result from dumper */
+
+    cmd = getresult(dumper->outfd, 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 */
+       log_add(L_WARNING, "%s pid %ld is messed up, ignoring it.\n",
+               dumper->name, (long)dumper->pid);
+       dumper->down = 1;       /* mark it down so it isn't used again */
+       failed = 1;     /* dump failed, must still finish up with taper */
+       break;
+
+    case DONE: /* DONE <handle> <origsize> <dumpsize> <dumptime> <err str> */
+       /* everything went fine */
+       origsize = (long)atof(result_argv[3]);
+       dumpsize = (long)atof(result_argv[4]);
+       dumptime = (long)atof(result_argv[5]);
+       break;
+
+    case NO_ROOM: /* NO-ROOM <handle> */
+       dumper_cmd(dumper, ABORT, dp);
+       cmd = getresult(dumper->outfd, 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> <err str> */
+    default:
+       /* dump failed, but we must still finish up with taper */
+       failed = 1;     /* problem with dump, possibly nonfatal */
+       break;
+       
+    case FAILED: /* FAILED <handle> <errstr> */
+       /* dump failed, but we must still finish up with taper */
+       failed = 2;     /* fatal problem with dump */
+       break;
+    }
+
+    /*
+     * Note that at this point, even if the dump above failed, it may
+     * not be a fatal failure if taper below says we can try again.
+     * E.g. a dumper failure above may actually be the result of a
+     * tape overflow, which in turn causes dump to see "broken pipe",
+     * "no space on device", etc., since taper closed the port first.
+     */
+
+    cmd = getresult(taper, 1, &result_argc, result_argv, MAX_ARGS+1);
+
+    switch(cmd) {
+    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);
+       }
+
+       if(failed == 1) goto tryagain;  /* dump didn't work */
+       else if(failed == 2) goto failed_dumper;
+
+       free_serial(result_argv[2]);
+
+       /* every thing went fine */
+       update_info_dumper(dp, origsize, dumpsize, dumptime);
+       filenum = 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
+          tape information.  */
+
+       break;
+
+    case TRYAGAIN: /* TRY-AGAIN <handle> <err mess> */
+    tryagain:
+       headqueue_disk(&runq, dp);
+    failed_dumper:
+       update_failed_dump_to_tape(dp);
+       free_serial(result_argv[2]);
+       tape_left = tape_length;
+       break;
+
+
+    case TAPE_ERROR: /* TAPE-ERROR <handle> <err mess> */
+    case BOGUS:
+    default:
+       update_failed_dump_to_tape(dp);
+       free_serial(result_argv[2]);
+       failed = 2;     /* fatal problem */
+       start_degraded_mode(&runq);
+    }
+
+    /* reset statistics & return */
+
+    taper_busy = dumper->busy = 0;
+    dp->host->inprogress -= 1;
+    dp->inprogress = 0;
+    deallocate_bandwidth(dp->host->netif, sched(dp)->est_kps);
+
+    inside_dump_to_tape = 0;
+    return failed;
+}
+
+int queue_length(q)
+disklist_t q;
+{
+    disk_t *p;
+    int len;
+
+    for(len = 0, p = q.head; p != NULL; len++, p = p->next);
+    return len;
+}
+
+
+void short_dump_state()
+{
+    int i, nidle;
+    char *wall_time;
+
+    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());
+    if(degraded_mode) printf("DOWN");
+    else if(!taper_busy) printf("idle");
+    else printf("writing");
+    nidle = 0;
+    for(i = 0; i < inparallel; i++) if(!dmptable[i].busy) nidle++;
+    printf(" idle-dumpers: %d", nidle);
+    printf(" qlen tapeq: %d", queue_length(tapeq));
+    printf(" runq: %d", queue_length(runq));
+    printf(" roomq: %d", queue_length(roomq));
+    printf(" wakeup: %d", (int)sleep_time.tv_sec);
+    printf(" driver-idle: %s\n", idle_strings[idle_reason]);
+    interface_state(wall_time);
+    holdingdisk_state(wall_time);
+    fflush(stdout);
+}
+
+void dump_state(str)
+char *str;
+{
+    int i;
+    disk_t *dp;
+
+    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());
+    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",
+               taper_disk->host->hostname, taper_disk->name,
+               sched(taper_disk)->level,
+               sched(taper_disk)->est_size);
+    for(i = 0; i < inparallel; i++) {
+       dp = dmptable[i].dp;
+       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,
+               sched(dp)->est_kps, sched(dp)->est_size, sched(dp)->est_time);
+    }
+    dump_queue("TAPE", tapeq, 5, stdout);
+    dump_queue("ROOM", roomq, 5, stdout);
+    dump_queue("RUN ", runq, 5, stdout);
+    printf("================\n");
+    fflush(stdout);
+}
diff --git a/server-src/driverio.c b/server-src/driverio.c
new file mode 100644 (file)
index 0000000..307135f
--- /dev/null
@@ -0,0 +1,606 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: driverio.c,v 1.35.2.14.4.2.2.5 2003/01/01 23:28:54 martinea Exp $
+ *
+ * I/O-related functions for driver program
+ */
+#include "amanda.h"
+#include "clock.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"
+
+void init_driverio()
+{
+    dumper_t *dumper;
+
+    taper = -1;
+
+    for(dumper = dmptable; dumper < dmptable + MAX_DUMPERS; dumper++) {
+       dumper->outfd = -1;
+    }
+}
+
+
+void addfd(fd, readset, maxfd)
+int    fd;
+fd_set *readset;
+int    *maxfd;
+{
+    if(fd < 0 || fd >= FD_SETSIZE) {
+       error("addfd: descriptor %d out of range (0 .. %d)\n",
+             fd, FD_SETSIZE-1);
+    }
+    if(readset != NULL)
+       FD_SET(fd, readset);
+    if(maxfd != NULL)
+       if(fd > *maxfd) *maxfd = fd;
+}
+
+char *childstr(fd)
+int fd;
+{
+    static char *str = NULL;
+    char fd_str[NUM_STR_SIZE];
+    dumper_t *dumper;
+
+    if(fd == taper) return "taper";
+
+    for(dumper = dmptable; dumper < dmptable + MAX_DUMPERS; dumper++)
+       if(dumper->outfd == fd) return dumper->name;
+
+    ap_snprintf(fd_str, sizeof(fd_str), "%d", fd);
+    str = newvstralloc(str, "unknown child (fd ", fd_str, ")", NULL);
+    return str;
+}
+
+
+void startup_tape_process(taper_program)
+char *taper_program;
+{
+    int fd[2];
+
+    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+       error("taper pipe: %s", strerror(errno));
+    if(fd[0] < 0 || fd[0] >= FD_SETSIZE) {
+       error("taper socketpair 0: descriptor %d out of range (0 .. %d)\n",
+             fd[0], FD_SETSIZE-1);
+    }
+    if(fd[1] < 0 || fd[1] >= FD_SETSIZE) {
+       error("taper socketpair 1: descriptor %d out of range (0 .. %d)\n",
+             fd[1], FD_SETSIZE-1);
+    }
+
+    switch(taper_pid = fork()) {
+    case -1:
+       error("fork taper: %s", strerror(errno));
+    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));
+    default:   /* parent process */
+       aclose(fd[1]);
+       taper = fd[0];
+       addfd(taper, &readset, &maxfd);
+    }
+}
+
+void startup_dump_process(dumper, dumper_program)
+dumper_t *dumper;
+char *dumper_program;
+{
+    int fd[2];
+
+    if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1)
+       error("%s pipe: %s", dumper->name, strerror(errno));
+
+    switch(dumper->pid = fork()) {
+    case -1:
+       error("fork %s: %s", dumper->name, strerror(errno));
+    case 0:            /* child process */
+       aclose(fd[0]);
+       if(dup2(fd[1], 0) == -1 || dup2(fd[1], 1) == -1)
+           error("%s dup2: %s", dumper->name, strerror(errno));
+       execle(dumper_program,
+              dumper->name ? dumper->name : "dumper",
+              config_name,
+              (char *)0,
+              safe_env());
+       error("exec %s (%s): %s", dumper_program,
+             dumper->name, strerror(errno));
+    default:   /* parent process */
+       aclose(fd[1]);
+       dumper->infd = dumper->outfd = fd[0];
+       addfd(dumper->outfd, &readset, &maxfd);
+       dumper->busy = dumper->down = 0;
+       dumper->dp = NULL;
+       fprintf(stderr,"driver: started %s pid %d\n",
+               dumper->name, dumper->pid);
+       fflush(stderr);
+    }
+}
+
+void startup_dump_processes(dumper_program, inparallel)
+char *dumper_program;
+int inparallel;
+{
+    int i;
+    dumper_t *dumper;
+    char number[NUM_STR_SIZE];
+
+    for(dumper = dmptable, i = 0; i < inparallel; dumper++, i++) {
+       ap_snprintf(number, sizeof(number), "%d", i);
+       dumper->name = stralloc2("dumper", number);
+
+       startup_dump_process(dumper, dumper_program);
+    }
+}
+
+cmd_t getresult(fd, show, result_argc, result_argv, max_arg)
+int fd;
+int show;
+int *result_argc;
+char **result_argv;
+int max_arg;
+{
+    int arg;
+    cmd_t t;
+    char *line;
+
+    if((line = areads(fd)) == NULL) {
+       if(errno) {
+           error("reading result from %s: %s", childstr(fd), strerror(errno));
+       }
+       *result_argc = 0;                               /* EOF */
+    } else {
+       *result_argc = split(line, result_argv, max_arg, " ");
+    }
+    amfree(line);
+
+    if(show) {
+       printf("driver: result time %s from %s:",
+              walltime_str(curclock()),
+              childstr(fd));
+       for(arg = 1; arg <= *result_argc; arg++)
+           printf(" %s", result_argv[arg]);
+       printf("\n");
+       fflush(stdout);
+    }
+
+#ifdef DEBUG
+    printf("argc = %d\n", *result_argc);
+    for(arg = 0; arg < *result_argc; arg++)
+       printf("argv[%d] = \"%s\"\n", arg, result_argv[arg]);
+#endif
+
+    if(*result_argc < 1) return BOGUS;
+
+    for(t = (cmd_t)(BOGUS+1); t < LAST_TOK; t++)
+       if(strcmp(result_argv[1], cmdstr[t]) == 0) return t;
+
+    return BOGUS;
+}
+
+
+int taper_cmd(cmd, /* optional */ ptr, destname, level, datestamp)
+cmd_t cmd;
+void *ptr;
+char *destname;
+int level;
+char *datestamp;
+{
+    char *cmdline = NULL;
+    char number[NUM_STR_SIZE];
+    disk_t *dp;
+    int l, n, s;
+    char *features;
+
+    switch(cmd) {
+    case START_TAPER:
+       cmdline = vstralloc(cmdstr[cmd], " ", (char *)ptr, "\n", NULL);
+       break;
+    case FILE_WRITE:
+       dp = (disk_t *) ptr;
+       ap_snprintf(number, sizeof(number), "%d", level);
+       features = am_feature_to_string(dp->host->features);
+       cmdline = vstralloc(cmdstr[cmd],
+                           " ", disk2serial(dp),
+                           " ", destname,
+                           " ", dp->host->hostname,
+                           " ", features,
+                           " ", dp->name,
+                           " ", number,
+                           " ", datestamp,
+                           "\n", NULL);
+       amfree(features);
+       break;
+    case PORT_WRITE:
+       dp = (disk_t *) ptr;
+       ap_snprintf(number, sizeof(number), "%d", level);
+       features = am_feature_to_string(dp->host->features);
+       cmdline = vstralloc(cmdstr[cmd],
+                           " ", disk2serial(dp),
+                           " ", dp->host->hostname,
+                           " ", features,
+                           " ", dp->name,
+                           " ", number,
+                           " ", datestamp,
+                           "\n", NULL);
+       amfree(features);
+       break;
+    case QUIT:
+       cmdline = stralloc2(cmdstr[cmd], "\n");
+       break;
+    default:
+       error("Don't know how to send %s command to taper", cmdstr[cmd]);
+    }
+    /*
+     * Note: cmdline already has a '\n'.
+     */
+    printf("driver: send-cmd time %s to taper: %s",
+          walltime_str(curclock()), cmdline);
+    fflush(stdout);
+    for(l = 0, n = strlen(cmdline); l < n; l += s) {
+       if((s = write(taper, cmdline + l, n - l)) < 0) {
+           printf("writing taper command: %s\n", strerror(errno));
+           fflush(stdout);
+           amfree(cmdline);
+           return 0;
+       }
+    }
+    amfree(cmdline);
+    return 1;
+}
+
+int dumper_cmd(dumper, cmd, /* optional */ dp)
+dumper_t *dumper;
+cmd_t cmd;
+disk_t *dp;
+{
+    char *cmdline = NULL;
+    char number[NUM_STR_SIZE];
+    char chunksize[NUM_STR_SIZE];
+    char use[NUM_STR_SIZE];
+    int l, n, s;
+    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";
+    }
+
+    switch(cmd) {
+    case FILE_DUMP:
+       holdalloc(h[activehd]->disk)->allocated_dumpers++;
+       ap_snprintf(number, sizeof(number), "%d", sched(dp)->level);
+       ap_snprintf(chunksize, sizeof(chunksize), "%ld", h[0]->disk->chunksize);
+       ap_snprintf(use, sizeof(use), "%ld", h[0]->reserved );
+       features = am_feature_to_string(dp->host->features);
+       o = optionstr(dp, dp->host->features, NULL);
+       cmdline = vstralloc(cmdstr[cmd],
+                           " ", disk2serial(dp),
+                           " ", sched(dp)->destname,
+                           " ", dp->host->hostname,
+                           " ", features,
+                           " ", dp->name,
+                           " ", device,
+                           " ", number,
+                           " ", sched(dp)->dumpdate,
+                           " ", chunksize,
+                           " ", dp->program,
+                           " ", use,
+                           " |", o,
+                           "\n", NULL);
+       amfree(features);
+       amfree(o);
+       break;
+    case PORT_DUMP:
+       ap_snprintf(number, sizeof(number), "%d", sched(dp)->level);
+       features = am_feature_to_string(dp->host->features);
+       o = optionstr(dp, dp->host->features, NULL);
+       cmdline = vstralloc(cmdstr[cmd],
+                           " ", disk2serial(dp),
+                           " ", sched(dp)->destname,
+                           " ", dp->host->hostname,
+                           " ", features,
+                           " ", dp->name,
+                           " ", device,
+                           " ", number,
+                           " ", sched(dp)->dumpdate,
+                           " ", dp->program,
+                           " |", o,
+                           "\n", NULL);
+       amfree(features);
+       amfree(o);
+       break;
+    case QUIT:
+    case ABORT:
+       if( dp ) {
+           cmdline = vstralloc(cmdstr[cmd],
+                               " ", sched(dp)->destname,
+                               "\n", NULL );
+       } else {
+           cmdline = stralloc2(cmdstr[cmd], "\n");
+       }
+       break;
+    case CONTINUE:
+       if( dp ) {
+           holdalloc(h[activehd]->disk)->allocated_dumpers++;
+           ap_snprintf(chunksize, sizeof(chunksize), "%ld", 
+                       h[activehd]->disk->chunksize );
+           ap_snprintf(use, sizeof(use), "%ld", 
+                       h[activehd]->reserved - h[activehd]->used );
+           cmdline = vstralloc(cmdstr[cmd],
+                               " ", h[activehd]->destname,
+                               " ", chunksize,
+                               " ", use,
+                               "\n", NULL );
+       } else {
+           cmdline = stralloc2(cmdstr[cmd], "\n");
+       }
+       break;
+    default:
+       error("Don't know how to send %s command to dumper", cmdstr[cmd]);
+    }
+    /*
+     * Note: cmdline already has a '\n'.
+     */
+    if(dumper->down) {
+       printf("driver: send-cmd time %s ignored to down dumper %s: %s",
+              walltime_str(curclock()), dumper->name, cmdline);
+    } else {
+       printf("driver: send-cmd time %s to %s: %s",
+              walltime_str(curclock()), dumper->name, cmdline);
+       fflush(stdout);
+       for(l = 0, n = strlen(cmdline); l < n; l += s) {
+           if((s = write(dumper->infd, cmdline + l, n - l)) < 0) {
+               printf("writing %s command: %s\n", dumper->name, 
+                      strerror(errno));
+               fflush(stdout);
+               amfree(cmdline);
+               return 0;
+           }
+       }
+    }
+    amfree(cmdline);
+    return 1;
+}
+
+#define MAX_SERIAL MAX_DUMPERS+1       /* one for the taper */
+
+long generation = 1;
+
+struct serial_s {
+    long gen;
+    disk_t *dp;
+} stable[MAX_SERIAL];
+
+disk_t *serial2disk(str)
+char *str;
+{
+    int rc, s;
+    long gen;
+
+    rc = sscanf(str, "%d-%ld", &s, &gen);
+    if(rc != 2) {
+       error("error [serial2disk \"%s\" parse error]", str);
+    } else if (s < 0 || s >= MAX_SERIAL) {
+       error("error [serial out of range 0..%d: %d]", MAX_SERIAL, s);
+    }
+    if(gen != stable[s].gen)
+       printf("driver: error time %s serial gen mismatch\n",
+              walltime_str(curclock()));
+    return stable[s].dp;
+}
+
+void free_serial(str)
+char *str;
+{
+    int rc, s;
+    long gen;
+
+    rc = sscanf(str, "%d-%ld", &s, &gen);
+    if(!(rc == 2 && s >= 0 && s < MAX_SERIAL)) {
+       /* nuke self to get core dump for Brett */
+       fprintf(stderr, "driver: free_serial: str \"%s\" rc %d s %d\n",
+               str, rc, s);
+       fflush(stderr);
+       abort();
+    }
+
+    if(gen != stable[s].gen)
+       printf("driver: error time %s serial gen mismatch\n",
+              walltime_str(curclock()));
+    stable[s].gen = 0;
+}
+
+
+char *disk2serial(dp)
+disk_t *dp;
+{
+    int s;
+    static char str[NUM_STR_SIZE];
+
+    /* find unused serial number */
+    for(s = 0; s < MAX_SERIAL; s++) if(stable[s].gen == 0) break;
+    if(s >= MAX_SERIAL) {
+       printf("driver: error time %s bug: out of serial numbers\n",
+              walltime_str(curclock()));
+       s = 0;
+    }
+
+    stable[s].gen = generation++;
+    stable[s].dp = dp;
+
+    ap_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;
+{
+    int level, i;
+    info_t info;
+    stats_t *infp;
+    perf_t *perfp;
+    char *conf_infofile;
+
+    level = sched(dp)->level;
+
+    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)) {
+       error("could not open info db \"%s\"", conf_infofile);
+    }
+    amfree(conf_infofile);
+
+    get_info(dp->host->hostname, dp->name, &info);
+
+    /* Clean up information about this and higher-level dumps.  This
+       assumes that update_info_dumper() is always run before
+       update_info_taper(). */
+    for (i = level; i < DUMP_LEVELS; ++i) {
+      infp = &info.inf[i];
+      infp->size = -1;
+      infp->csize = -1;
+      infp->secs = -1;
+      infp->date = (time_t)-1;
+      infp->label[0] = '\0';
+      infp->filenum = 0;
+    }
+
+    /* now store information about this dump */
+    infp = &info.inf[level];
+    infp->size = origsize;
+    infp->csize = dumpsize;
+    infp->secs = dumptime;
+    infp->date = sched(dp)->timestamp;
+
+    if(level == 0) perfp = &info.full;
+    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(dumptime > 0L) {
+       if(dumptime >= dumpsize)
+           newperf(perfp->rate, 1);
+       else
+           newperf(perfp->rate, dumpsize/dumptime);
+    }
+
+    if(getconf_int(CNF_RESERVE)<100) {
+       info.command = NO_COMMAND;
+    }
+
+    if(level == info.last_level)
+       info.consecutive_runs++;
+    else {
+       info.last_level = level;
+       info.consecutive_runs = 1;
+    }
+    if(put_info(dp->host->hostname, dp->name, &info))
+       error("infofile update failed (%s,%s)\n", dp->host->hostname, dp->name);
+
+    close_infofile();
+}
+
+void update_info_taper(dp, label, filenum, level)
+disk_t *dp;
+char *label;
+int filenum;
+int level;
+{
+    info_t info;
+    stats_t *infp;
+    int rc;
+
+    rc = open_infofile(getconf_str(CNF_INFOFILE));
+    if(rc)
+       error("could not open infofile %s: %s (%d)", getconf_str(CNF_INFOFILE),
+             strerror(errno), rc);
+
+    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';
+    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);
+
+    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;
+{
+    int i;
+
+    if( !ahd ) { return; }
+
+    for( i = 0; ahd[i]; i++ ) {
+       amfree(ahd[i]->destname);
+       amfree(ahd[i]);
+    }
+    amfree(ahd);
+}
diff --git a/server-src/driverio.h b/server-src/driverio.h
new file mode 100644 (file)
index 0000000..bb5db74
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: driverio.h,v 1.13.2.7.4.3 2001/11/08 18:44:56 martinea Exp $
+ *
+ * driver-related helper functions
+ */
+
+#include "holding.h"
+#include "server_util.h"
+
+#define MAX_DUMPERS 63
+
+#ifndef GLOBAL
+#define GLOBAL extern
+#endif
+
+/* dumper process structure */
+
+typedef struct dumper_s {
+    char *name;                /* name of this dumper */
+    int pid;           /* its pid */
+    int busy, down;
+    int infd, outfd;
+    disk_t *dp;
+} dumper_t;
+
+typedef struct assignedhd_s {
+    holdingdisk_t      *disk;
+    long               used;
+    long               reserved;
+    char               *destname;
+} assignedhd_t;
+
+/* schedule structure */
+
+typedef struct sched_s {
+    int attempted, priority;
+    int level, degr_level;
+    long est_time, degr_time;
+    unsigned long est_size, degr_size, act_size;
+    char *dumpdate, *degr_dumpdate;
+    int est_kps, degr_kps;
+    char *destname;                            /* file/port name */
+    dumper_t *dumper;
+    assignedhd_t **holdp;
+    time_t timestamp;
+    char *datestamp;
+    int activehd;
+    int no_space;
+} sched_t;
+
+#define sched(dp)      ((sched_t *) (dp)->up)
+
+
+/* holding disk reservation structure */
+
+typedef struct holdalloc_s {
+    int allocated_dumpers;
+    long allocated_space;
+} holdalloc_t;
+
+#define holdalloc(hp)  ((holdalloc_t *) (hp)->up)
+
+GLOBAL dumper_t dmptable[MAX_DUMPERS];
+
+GLOBAL int maxfd;
+GLOBAL fd_set readset;
+GLOBAL int taper, taper_busy, taper_pid;
+
+void init_driverio();
+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));
+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));
+disk_t *serial2disk P((char *str));
+void free_serial P((char *str));
+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));
diff --git a/server-src/dumper-krb4.c b/server-src/dumper-krb4.c
new file mode 100644 (file)
index 0000000..6dcca07
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991,1994 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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * dumper-krb4.c - those bits of dumper code that deal with encrypting
+ *                data streams over the network.  Even though these just
+ *                call the underlying DES routines, the U.S. government
+ *                considers this a munition.  Go figure.
+ */
+#include "krb4-security.h"
+
+/*
+ * NOTE:  This symbol must be the same as DATABUF_SIZE in
+ * client-src/sendbackup-krb4.c
+ * so that the encrypt/decrypt routines are working on the same sized buffers.
+ * Really, this should be moved out of dumper.c so that both programs can use
+ * the same symbol.  Hopefully that can be done later.  This is good enough
+ * to get encryption working for now...
+ *
+ *                  - Chris Ross (cross@uu.net)  4-Jun-1998
+ */
+#define        DATABUF_SIZE    DISK_BLOCK_BYTES
+
+int kamanda_port;
+CREDENTIALS cred;
+
+des_key_schedule sched;
+
+void decrypt_initialize()
+{
+    des_key_sched(cred.session, sched);
+}
+
+decrypt_buffer(buffer, size)
+char *buffer;
+int size;
+{
+    des_pcbc_encrypt((des_cblock *)buffer, 
+                    (des_cblock *)buffer, 
+                     size, sched, (des_cblock *)cred.session, DES_DECRYPT);
+}
+
+#define NAUGHTY_BITS_INITIALIZE                \
+    if(kencrypt) decrypt_initialize()
+
+#define NAUGHTY_BITS                   \
+    if(kencrypt) decrypt_buffer(databuf, DATABUF_SIZE)
diff --git a/server-src/dumper.c b/server-src/dumper.c
new file mode 100644 (file)
index 0000000..48b8d10
--- /dev/null
@@ -0,0 +1,1874 @@
+/*
+ * 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: dumper.c,v 1.75.2.14.2.7.2.17 2003/10/30 18:09:27 martinea Exp $
+ *
+ * requests remote amandad processes to dump filesystems
+ */
+#include "amanda.h"
+#include "amindex.h"
+#include "arglist.h"
+#include "clock.h"
+#include "conffile.h"
+#include "logfile.h"
+#include "protocol.h"
+#include "stream.h"
+#include "token.h"
+#include "version.h"
+#include "fileheader.h"
+#include "amfeatures.h"
+#include "server_util.h"
+#include "holding.h"
+
+#ifdef KRB4_SECURITY
+#include "dumper-krb4.c"
+#else
+#define NAUGHTY_BITS_INITIALIZE                /* I'd tell you what these do */
+#define NAUGHTY_BITS                   /* but then I'd have to kill you */
+#endif
+
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#define CONNECT_TIMEOUT        5*60
+#define MESGBUF_SIZE   4*1024
+
+#define STARTUP_TIMEOUT 60
+
+int interactive;
+char *handle = NULL;
+
+char databuf[DISK_BLOCK_BYTES];
+char mesgbuf[MESGBUF_SIZE+1];
+char *errstr = NULL;
+char *datain;                          /* where to read in data */
+char *dataout;                         /* where to write out data */
+char *datalimit;                       /* end of the data area */
+int abort_pending;
+long dumpsize;                         /* total size of dump */
+long dumpbytes;
+long origsize;
+long filesize;                         /* size of current holding disk file */
+int nb_header_block;
+static enum { srvcomp_none, srvcomp_fast, srvcomp_best } srvcompress;
+
+static FILE *errf = NULL;
+char *filename = NULL;                 /* holding disk base file name */
+string_t cont_filename;
+char *hostname = NULL;
+am_feature_t *their_features = NULL;
+char *diskname = NULL;
+char *device = NULL;
+char *options = NULL;
+char *progname = NULL;
+int level;
+char *dumpdate = NULL;
+long chunksize;
+long use;                              /* space remaining in this hold disk */
+char *datestamp;
+char *backup_name = NULL;
+char *recover_cmd = NULL;
+char *compress_suffix = NULL;
+int conf_dtimeout;
+
+dumpfile_t file;
+int filename_seq;
+long split_size;                       /* next dumpsize we will split at */
+
+int datafd = -1;
+int mesgfd = -1;
+int indexfd = -1;
+int amanda_port;
+
+static am_feature_t *our_features = NULL;
+static char *our_feature_string = NULL;
+
+/* local functions */
+int main P((int main_argc, char **main_argv));
+int do_dump P((int mesgfd, int datafd, int indexfd, int outfd));
+void check_options P((char *options));
+void service_ports_init P((void));
+int write_tapeheader P((int outfd, dumpfile_t *type));
+int write_dataptr P((int outf));
+int update_dataptr P((int *outf, int size));
+static void process_dumpeof P((void));
+static void process_dumpline P((char *str));
+static void add_msg_data P((char *str, int len));
+static void log_msgout P((logtype_t typ));
+void sendbackup_response P((proto_t *p, pkt_t *pkt));
+int startup_dump P((char *hostname, char *disk, char *device, int level,
+                   char *dumpdate, char *progname, char *options));
+
+
+void check_options(options)
+char *options;
+{
+#ifdef KRB4_SECURITY
+    krb4_auth = strstr(options, "krb4-auth;") != NULL;
+    kencrypt = strstr(options, "kencrypt;") != NULL;
+#endif
+    if (strstr(options, "srvcomp-best;") != NULL)
+      srvcompress = srvcomp_best;
+    else if (strstr(options, "srvcomp-fast;") != NULL)
+      srvcompress = srvcomp_fast;
+    else
+      srvcompress = srvcomp_none;
+}
+
+void service_ports_init()
+{
+    struct servent *amandad;
+
+    if((amandad = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL) {
+       amanda_port = AMANDA_SERVICE_DEFAULT;
+       log_add(L_WARNING, "no %s/udp service, using default port %d",
+               AMANDA_SERVICE_NAME, AMANDA_SERVICE_DEFAULT);
+    }
+    else
+       amanda_port = ntohs(amandad->s_port);
+
+#ifdef KRB4_SECURITY
+    if((amandad = getservbyname(KAMANDA_SERVICE_NAME, "udp")) == NULL) {
+       kamanda_port = KAMANDA_SERVICE_DEFAULT;
+       log_add(L_WARNING, "no %s/udp service, using default port %d",
+               KAMANDA_SERVICE_NAME, KAMANDA_SERVICE_DEFAULT);
+    }
+    else
+       kamanda_port = ntohs(amandad->s_port);
+#endif
+}
+
+
+int main(main_argc, main_argv)
+int main_argc;
+char **main_argv;
+{
+    struct cmdargs cmdargs;
+    cmd_t cmd;
+    int outfd, protocol_port, taper_port, rc;
+    dgram_t *msg;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    char *conffile;
+    char *q = NULL;
+    int fd;
+    char *tmp_filename = NULL, *pc;
+    int a;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("dumper");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
+    set_logerror(logerror);
+
+    if (main_argc > 1) {
+       config_name = stralloc(main_argv[1]);
+       config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+    } else {
+       char my_cwd[STR_SIZE];
+
+       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+           error("cannot determine current working directory");
+       }
+       config_dir = stralloc2(my_cwd, "/");
+       if ((config_name = strrchr(my_cwd, '/')) != NULL) {
+           config_name = stralloc(config_name + 1);
+       }
+    }
+
+    safe_cd();
+
+    our_features = am_init_feature_set();
+    our_feature_string = am_feature_to_string(our_features);
+
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if(read_conffile(conffile)) {
+       error("errors processing config file \"%s\"", conffile);
+    }
+    amfree(conffile);
+
+    /* set up dgram port first thing */
+
+    msg = dgram_alloc();
+    if(dgram_bind(msg, &protocol_port) == -1)
+       error("could not bind result datagram port: %s", strerror(errno));
+
+    if(geteuid() == 0) {
+       /* set both real and effective uid's to real uid, likewise for gid */
+       setgid(getgid());
+       setuid(getuid());
+    }
+#ifdef BSD_SECURITY
+    else error("must be run setuid root to communicate correctly");
+#endif
+
+    fprintf(stderr,
+           "%s: pid %ld executable %s version %s, using port %d\n",
+           get_pname(), (long) getpid(),
+           main_argv[0], version(), protocol_port);
+    fflush(stderr);
+
+    /* now, make sure we are a valid user */
+
+    if(getpwuid(getuid()) == NULL)
+       error("can't get login name for my uid %ld", (long)getuid());
+
+    signal(SIGPIPE, SIG_IGN);
+
+    interactive = isatty(0);
+
+    amfree(datestamp);
+    datestamp = construct_datestamp(NULL);
+    conf_dtimeout = getconf_int(CNF_DTIMEOUT);
+
+    service_ports_init();
+    proto_init(msg->socket, time(0), 16);
+
+    do {
+       cmd = getcmd(&cmdargs);
+
+       switch(cmd) {
+       case QUIT:
+           break;
+       case FILE_DUMP:
+           /*
+            * FILE-DUMP
+            *   handle
+            *   filename
+            *   host
+            *   features
+            *   disk
+            *   device
+            *   level
+            *   dumpdate
+            *   chunksize
+            *   progname
+            *   use
+            *   options
+            */
+           cmdargs.argc++;                     /* true count of args */
+           a = 2;
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: handle]");
+           }
+           handle = newstralloc(handle, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: filename]");
+           }
+           filename = newstralloc(filename, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: hostname]");
+           }
+           hostname = newstralloc(hostname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: features]");
+           }
+           am_release_feature_set(their_features);
+           their_features = am_string_to_feature(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: diskname]");
+           }
+           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: device]");
+           }
+           device = newstralloc(device, cmdargs.argv[a++]);
+           if(strcmp(device, "NODEVICE") == 0) amfree(device);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: level]");
+           }
+           level = atoi(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: dumpdate]");
+           }
+           dumpdate = newstralloc(dumpdate, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: chunksize]");
+           }
+           chunksize = am_floor(atoi(cmdargs.argv[a++]), DISK_BLOCK_KB);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: progname]");
+           }
+           progname = newstralloc(progname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: use]");
+           }
+           use = am_floor(atoi(cmdargs.argv[a++]), DISK_BLOCK_KB);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper FILE-DUMP: not enough args: options]");
+           }
+           options = newstralloc(options, cmdargs.argv[a++]);
+
+           if(a != cmdargs.argc) {
+               error("error [dumper FILE-DUMP: too many args: %d != %d]",
+                     cmdargs.argc, a);
+           }
+
+           cont_filename[0] = '\0';
+
+           tmp_filename = newvstralloc(tmp_filename, filename, ".tmp", NULL);
+           pc = strrchr(tmp_filename, '/');
+           *pc = '\0';
+           mkholdingdir(tmp_filename);
+           *pc = '/';
+           outfd = open(tmp_filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
+           if(outfd == -1) {
+               int save_errno = errno;
+               q = squotef("[main holding file \"%s\": %s]",
+                           tmp_filename, strerror(errno));
+               if(save_errno == ENOSPC) {
+                   putresult(NO_ROOM, "%s %lu\n", handle, use);
+                   putresult(TRYAGAIN, "%s %s\n", handle, q);
+               }
+               else {
+                   putresult(FAILED, "%s %s\n", handle, q);
+               }
+               amfree(q);
+               break;
+           }
+           filename_seq = 1;
+
+           check_options(options);
+
+           rc = startup_dump(hostname,
+                             diskname,
+                             device,
+                             level,
+                             dumpdate,
+                             progname,
+                             options);
+           if(rc) {
+               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);
+               }
+               amfree(q);
+               /* do need to close if TRY-AGAIN, doesn't hurt otherwise */
+               if (mesgfd != -1)
+                   aclose(mesgfd);
+               if (datafd != -1)
+                   aclose(datafd);
+               if (indexfd != -1)
+                   aclose(indexfd);
+               if (outfd != -1)
+                   aclose(outfd);
+               break;
+           }
+
+           abort_pending = 0;
+           split_size = (chunksize>use)?use:chunksize;
+           use -= split_size;
+           if(do_dump(mesgfd, datafd, indexfd, outfd)) {
+           }
+           aclose(mesgfd);
+           aclose(datafd);
+           if (indexfd != -1)
+               aclose(indexfd);
+           aclose(outfd);
+           if(abort_pending) putresult(ABORT_FINISHED, "%s\n", handle);
+           break;
+
+       case PORT_DUMP:
+           /*
+            * PORT-DUMP
+            *   handle
+            *   port
+            *   host
+            *   features
+            *   disk
+            *   device
+            *   level
+            *   dumpdate
+            *   progname
+            *   options
+            */
+           cmdargs.argc++;                     /* true count of args */
+           a = 2;
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: handle]");
+           }
+           handle = newstralloc(handle, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: port]");
+           }
+           taper_port = atoi(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: hostname]");
+           }
+           hostname = newstralloc(hostname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: features]");
+           }
+           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: diskname]");
+           }
+           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: device]");
+           }
+           device = newstralloc(device, cmdargs.argv[a++]);
+           if(strcmp(device,"NODEVICE") == 0) amfree(device);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: level]");
+           }
+           level = atoi(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: dumpdate]");
+           }
+           dumpdate = newstralloc(dumpdate, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [dumper PORT-DUMP: not enough args: progname]");
+           }
+           progname = newstralloc(progname, 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);
+           }
+
+           filename = newstralloc(filename, "<taper program>");
+           cont_filename[0] = '\0';
+
+           /* connect outf to taper port */
+
+           outfd = stream_client("localhost", taper_port,
+                                 STREAM_BUFSIZE, -1, NULL);
+           if(outfd == -1) {
+               q = squotef("[taper port open: %s]", strerror(errno));
+               putresult(FAILED, "%s %s\n", handle, q);
+               amfree(q);
+               break;
+           }
+           filename_seq = 1;
+
+           check_options(options);
+
+           rc = startup_dump(hostname,
+                             diskname,
+                             device,
+                             level,
+                             dumpdate,
+                             progname,
+                             options);
+           if(rc) {
+               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);
+               }
+               amfree(q);
+               /* do need to close if TRY-AGAIN, doesn't hurt otherwise */
+               if (mesgfd != -1)
+                   aclose(mesgfd);
+               if (datafd != -1)
+                   aclose(datafd);
+               if (indexfd != -1)
+                   aclose(indexfd);
+               if (outfd != -1)
+                   aclose(outfd);
+               break;
+           }
+
+           abort_pending = 0;
+           split_size = -1;
+           if(do_dump(mesgfd, datafd, indexfd, outfd)) {
+           }
+           aclose(mesgfd);
+           aclose(datafd);
+           if (indexfd != -1)
+               aclose(indexfd);
+           aclose(outfd);
+           if(abort_pending) putresult(ABORT_FINISHED, "%s\n", handle);
+           break;
+
+       default:
+           if(cmdargs.argc >= 1) {
+               q = squote(cmdargs.argv[1]);
+           } else if(cmdargs.argc >= 0) {
+               q = squote(cmdargs.argv[0]);
+           } else {
+               q = stralloc("(no input?)");
+           }
+           putresult(BAD_COMMAND, "%s\n", q);
+           amfree(q);
+       }
+       while(wait(NULL) != -1);
+    } while(cmd != QUIT);
+
+    amfree(tmp_filename);
+    amfree(errstr);
+    amfree(msg);
+    amfree(datestamp);
+    amfree(backup_name);
+    amfree(recover_cmd);
+    amfree(compress_suffix);
+    amfree(handle);
+    amfree(filename);
+    amfree(hostname);
+    amfree(diskname);
+    amfree(device);
+    amfree(dumpdate);
+    amfree(progname);
+    amfree(options);
+    amfree(config_dir);
+    amfree(config_name);
+    amfree(our_feature_string);
+    am_release_feature_set(our_features);
+    our_features = NULL;
+    am_release_feature_set(their_features);
+    their_features = NULL;
+
+    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 0;
+}
+
+
+int write_dataptr(outf)
+int outf;
+{
+    int w;
+    int written;
+
+    written = w = 0;
+    while(dataout < datain) {
+       if((w = write(outf, dataout, datain - dataout)) < 0) {
+           break;
+       }
+       dataout += w;
+       written += w;
+    }
+    dumpbytes += written;
+    dumpsize += (dumpbytes / 1024);
+    filesize += (dumpbytes / 1024);
+    dumpbytes %= 1024;
+    if(w < 0) {
+       if(errno != ENOSPC) {
+           errstr = squotef("data write: %s", strerror(errno));
+           return 1;
+       }
+       /*
+        * NO-ROOM is informational only.  Later, RQ_MORE_DISK will be
+        * issued to use another holding disk.
+        */
+       putresult(NO_ROOM, "%s %lu\n", handle, use+split_size-dumpsize);
+       use = 0;                                /* force RQ_MORE_DISK */
+       split_size = dumpsize;
+    }
+    if(dataout == datain) {
+       /*
+        * We flushed the whole buffer so reset to use it all.
+        */
+       dataout = datain = databuf;
+    }
+    return 0;
+}
+
+int update_dataptr(p_outfd, size)
+int *p_outfd, size;
+/*
+ * Updates the buffer pointer for the input data buffer.  The buffer is
+ * written if it is full or we are at EOF.
+ */
+{
+    int outfd = *p_outfd;
+    int rc = 0;
+    char *arg_filename = NULL;
+    char *new_filename = NULL;
+    char *tmp_filename = NULL;
+    char *pc;
+    char sequence[NUM_STR_SIZE];
+    int new_outfd = -1;
+    struct cmdargs cmdargs;
+    cmd_t cmd;
+    filetype_t save_type;
+    long left_in_chunk;
+    int a;
+    char *q;
+
+    datain += size;
+
+    while(rc == 0 && ((size == 0 && dataout < datain) || datain >= datalimit)) {
+
+       NAUGHTY_BITS;
+
+       while(size > 0 && split_size > 0 && dumpsize >= split_size) {
+           amfree(new_filename);
+           if(use == 0) {
+               /*
+                * Probably no more space on this disk.  Request more.
+                */
+                putresult(RQ_MORE_DISK, "%s\n", handle);
+                cmd = getcmd(&cmdargs);
+                if(cmd == CONTINUE) {
+                   /*
+                    * CONTINUE
+                    *   filename
+                    *   chunksize
+                    *   use
+                    */
+                   cmdargs.argc++;             /* true count of args */
+                   a = 2;
+
+                   if(a >= cmdargs.argc) {
+                       error("error [dumper CONTINUE: not enough args: filename]");
+                   }
+                   arg_filename = newstralloc(arg_filename, cmdargs.argv[a++]);
+
+                   if(a >= cmdargs.argc) {
+                       error("error [dumper CONTINUE: not enough args: chunksize]");
+                   }
+                   chunksize = atoi(cmdargs.argv[a++]);
+                   chunksize = am_floor(chunksize, DISK_BLOCK_KB);
+
+                   if(a >= cmdargs.argc) {
+                       error("error [dumper CONTINUE: not enough args: use]");
+                   }
+                    use = atoi(cmdargs.argv[a++]);
+
+                   if(a != cmdargs.argc) {
+                       error("error [dumper CONTINUE: too many args: %d != %d]",
+                             cmdargs.argc, a);
+                   }
+
+                   if(strcmp(filename, arg_filename) == 0) {
+                       /*
+                        * Same disk, so use what room is left up to the
+                        * next chunk boundary or the amount we were given,
+                        * whichever is less.
+                        */
+                       left_in_chunk = chunksize - filesize;
+                       if(left_in_chunk > use) {
+                           split_size += use;
+                           use = 0;
+                       } else {
+                           split_size += left_in_chunk;
+                           use -= left_in_chunk;
+                       }
+                       if(left_in_chunk > 0) {
+                           /*
+                            * We still have space in this chunk.
+                            */
+                           break;
+                       }
+                   } else {
+                       /*
+                        * Different disk, so use new file.
+                        */
+                       filename = newstralloc(filename, arg_filename);
+                   }
+                } else if(cmd == ABORT) {
+                    abort_pending = 1;
+                    errstr = newstralloc(errstr, "ERROR");
+                    rc = 1;
+                   goto common_exit;
+               } else {
+                   if(cmdargs.argc >= 1) {
+                       q = squote(cmdargs.argv[1]);
+                   } else if(cmdargs.argc >= 0) {
+                       q = squote(cmdargs.argv[0]);
+                   } else {
+                       q = stralloc("(no input?)");
+                   }
+                    error("error [bad command after RQ-MORE-DISK: \"%s\"]", q);
+                }
+           }
+
+           ap_snprintf(sequence, sizeof(sequence), "%d", filename_seq);
+           new_filename = newvstralloc(new_filename,
+                                       filename,
+                                       ".",
+                                       sequence,
+                                       NULL);
+           tmp_filename = newvstralloc(tmp_filename,
+                                       new_filename,
+                                       ".tmp",
+                                       NULL);
+           pc = strrchr(tmp_filename, '/');
+           *pc = '\0';
+           mkholdingdir(tmp_filename);
+           *pc = '/';
+           new_outfd = open(tmp_filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
+           if(new_outfd == -1) {
+               int save_errno = errno;
+
+               errstr = squotef("creating chunk holding file \"%s\": %s",
+                                tmp_filename,
+                                strerror(save_errno));
+               if(save_errno == ENOSPC) {
+                   putresult(NO_ROOM, "%s %lu\n",
+                             handle, 
+                             use + split_size - dumpsize);
+                   use = 0;            /* force RQ_MORE_DISK */
+                   split_size = dumpsize;
+                   continue;
+               }
+               aclose(outfd);
+               rc = 1;
+               goto common_exit;
+           }
+           save_type = file.type;
+           file.type = F_CONT_DUMPFILE;
+           file.cont_filename[0] = '\0';
+           if(write_tapeheader(new_outfd, &file)) {
+               int save_errno = errno;
+
+               aclose(new_outfd);
+               unlink(tmp_filename);
+               if(save_errno == ENOSPC) {
+                   putresult(NO_ROOM, "%s %lu\n",
+                             handle, 
+                             use + split_size - dumpsize);
+                   use = 0;                    /* force RQ_MORE_DISK */
+                   split_size = dumpsize;
+                   continue;
+               }
+               errstr = squotef("write_tapeheader file \"%s\": %s",
+                                tmp_filename, strerror(errno));
+               rc = 1;
+               goto common_exit;
+           }
+           if(lseek(outfd, (off_t)0, SEEK_SET) != 0) {
+               errstr = squotef("cannot lseek: %s", strerror(errno));
+               aclose(new_outfd);
+               unlink(tmp_filename);
+               rc = 1;
+               goto common_exit;
+           }
+           strncpy(file.cont_filename, new_filename, 
+                   sizeof(file.cont_filename));
+           file.cont_filename[sizeof(file.cont_filename)-1] = '\0';
+           file.type = save_type;
+           if(write_tapeheader(outfd, &file)) {
+               errstr = squotef("write_tapeheader file linked to \"%s\": %s",
+                                tmp_filename, strerror(errno));
+               aclose(new_outfd);
+               unlink(tmp_filename);
+               rc = 1;
+               goto common_exit;
+           }
+           file.type = F_CONT_DUMPFILE;
+           strncpy(cont_filename, new_filename, sizeof(cont_filename));
+           cont_filename[sizeof(cont_filename)-1] = '\0';
+
+           aclose(outfd);
+           *p_outfd = outfd = new_outfd;
+           new_outfd = -1;
+
+           dumpsize += DISK_BLOCK_KB;
+           filesize = DISK_BLOCK_KB;
+           split_size += (chunksize>use)?use:chunksize;
+           use = (chunksize>use)?0:use-chunksize;
+           nb_header_block++;
+           filename_seq++;
+       }
+       rc = write_dataptr(outfd);
+    }
+
+common_exit:
+
+    amfree(new_filename);
+    amfree(tmp_filename);
+    amfree(arg_filename);
+    return rc;
+}
+
+
+static char *msgbuf = NULL;
+int got_info_endline;
+int got_sizeline;
+int got_endline;
+int dump_result;
+
+static void process_dumpeof()
+{
+    /* process any partial line in msgbuf? !!! */
+    if(msgbuf != NULL) {
+       fprintf(errf,"? %s: error [partial line in msgbuf: %ld bytes]\n",
+               get_pname(), (long) strlen(msgbuf));
+       fprintf(errf,"? %s: error [partial line in msgbuf: \"%s\"]\n",
+               get_pname(), msgbuf);
+    }
+    if(!got_sizeline && dump_result < 2) {
+       /* make a note if there isn't already a failure */
+       fprintf(errf,"? %s: strange [missing size line from sendbackup]\n",
+               get_pname());
+       dump_result = max(dump_result, 2);
+    }
+
+    if(!got_endline && dump_result < 2) {
+       fprintf(errf,"? %s: strange [missing end line from sendbackup]\n",
+               get_pname());
+       dump_result = max(dump_result, 2);
+    }
+}
+
+/* Parse an information line from the client.
+** We ignore unknown parameters and only remember the last
+** of any duplicates.
+*/
+static void parse_info_line(str)
+char *str;
+{
+    if(strcmp(str, "end") == 0) {
+       got_info_endline = 1;
+       return;
+    }
+
+#define sc "BACKUP="
+    if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+       backup_name = newstralloc(backup_name, str + sizeof(sc)-1);
+       return;
+    }
+#undef sc
+
+#define sc "RECOVER_CMD="
+    if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+       recover_cmd = newstralloc(recover_cmd, str + sizeof(sc)-1);
+       return;
+    }
+#undef sc
+
+#define sc "COMPRESS_SUFFIX="
+    if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+       compress_suffix = newstralloc(compress_suffix, str + sizeof(sc)-1);
+       return;
+    }
+#undef sc
+}
+
+static void process_dumpline(str)
+char *str;
+{
+    char *s, *fp;
+    int ch;
+
+    s = str;
+    ch = *s++;
+
+    switch(ch) {
+    case '|':
+       /* normal backup output line */
+       break;
+    case '?':
+       /* sendbackup detected something strange */
+       dump_result = max(dump_result, 1);
+       break;
+    case 's':
+       /* a sendbackup line, just check them all since there are only 5 */
+#define sc "sendbackup: start"
+       if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+           break;
+       }
+#undef sc
+#define sc "sendbackup: size"
+       if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+           s += sizeof(sc)-1;
+           ch = s[-1];
+           skip_whitespace(s, ch);
+           if(ch) {
+               origsize = (long)atof(str + sizeof(sc)-1);
+               got_sizeline = 1;
+               break;
+           }
+       }
+#undef sc
+#define sc "sendbackup: end"
+       if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+           got_endline = 1;
+           break;
+       }
+#undef sc
+#define sc "sendbackup: error"
+       if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+           s += sizeof(sc)-1;
+           ch = s[-1];
+#undef sc
+           got_endline = 1;
+           dump_result = max(dump_result, 2);
+           skip_whitespace(s, ch);
+           if(ch == '\0' || ch != '[') {
+               errstr = newvstralloc(errstr,
+                                     "bad remote error: ", str,
+                                     NULL);
+           } else {
+               ch = *s++;
+               fp = s - 1;
+               while(ch && ch != ']') ch = *s++;
+               s[-1] = '\0';
+               errstr = newstralloc(errstr, fp);
+               s[-1] = ch;
+           }
+           break;
+       }
+#define sc "sendbackup: info"
+       if(strncmp(str, sc, sizeof(sc)-1) == 0) {
+           s += sizeof(sc)-1;
+           ch = s[-1];
+           skip_whitespace(s, ch);
+           parse_info_line(s - 1);
+           break;
+       }
+#undef sc
+       /* else we fall through to bad line */
+    default:
+       fprintf(errf, "??%s", str);
+       dump_result = max(dump_result, 1);
+       return;
+    }
+    fprintf(errf, "%s\n", str);
+}
+
+static void add_msg_data(str, len)
+char *str;
+int len;
+{
+    char *t;
+    char *nl;
+
+    while(len > 0) {
+       if((nl = strchr(str, '\n')) != NULL) {
+           *nl = '\0';
+       }
+       if(msgbuf) {
+           t = stralloc2(msgbuf, str);
+           amfree(msgbuf);
+           msgbuf = t;
+       } else if(nl == NULL) {
+           msgbuf = stralloc(str);
+       } else {
+           msgbuf = str;
+       }
+       if(nl == NULL) break;
+       process_dumpline(msgbuf);
+       if(msgbuf != str) free(msgbuf);
+       msgbuf = NULL;
+       len -= nl + 1 - str;
+       str = nl + 1;
+    }
+}
+
+
+static void log_msgout(typ)
+logtype_t typ;
+{
+    char *line = NULL;
+
+    fflush(errf);
+    (void) fseek(errf, 0L, SEEK_SET);
+    for(; (line = agets(errf)) != NULL; free(line)) {
+       log_add(typ, "%s", line);
+    }
+    afclose(errf);
+}
+
+/* ------------- */
+
+void make_tapeheader(file, type)
+dumpfile_t *file;
+filetype_t type;
+{
+    fh_init(file);
+    file->type = type;
+    strncpy(file->datestamp  , datestamp  , sizeof(file->datestamp)-1);
+    file->datestamp[sizeof(file->datestamp)-1] = '\0';
+    strncpy(file->name       , hostname   , sizeof(file->name)-1);
+    file->name[sizeof(file->name)-1] = '\0';
+    strncpy(file->disk       , diskname   , sizeof(file->disk)-1);
+    file->disk[sizeof(file->disk)-1] = '\0';
+    file->dumplevel = level;
+    strncpy(file->program    , backup_name, sizeof(file->program)-1);
+    file->program[sizeof(file->program)-1] = '\0';
+    strncpy(file->recover_cmd, recover_cmd, sizeof(file->recover_cmd)-1);
+    file->recover_cmd[sizeof(file->recover_cmd)-1] = '\0';
+    file->blocksize = DISK_BLOCK_BYTES;
+
+    if (srvcompress) {
+       file->compressed=1;
+       ap_snprintf(file->uncompress_cmd, sizeof(file->uncompress_cmd),
+                   " %s %s |", UNCOMPRESS_PATH,
+#ifdef UNCOMPRESS_OPT
+                   UNCOMPRESS_OPT
+#else
+                   ""
+#endif
+                   );
+       strncpy(file->comp_suffix, COMPRESS_SUFFIX,sizeof(file->comp_suffix)-1);
+       file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+    }
+    else {
+       file->uncompress_cmd[0] = '\0';
+       file->compressed=compress_suffix!=NULL;
+       if(compress_suffix) {
+           strncpy(file->comp_suffix, compress_suffix,
+                   sizeof(file->comp_suffix)-1);
+           file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+       } else {
+           strncpy(file->comp_suffix, "N", sizeof(file->comp_suffix)-1);
+           file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
+       }
+    }
+    strncpy(file->cont_filename, cont_filename, sizeof(file->cont_filename)-1);
+    file->cont_filename[sizeof(file->cont_filename)-1] = '\0';
+}
+
+/* Send an Amanda dump header to the output file.
+ * returns true if an error occured, false on success
+ */
+
+int write_tapeheader(outfd, file)
+int outfd;
+dumpfile_t *file;
+{
+    char buffer[DISK_BLOCK_BYTES];
+    int         written;
+
+    build_header(buffer, file, sizeof(buffer));
+
+    written = fullwrite(outfd, buffer, sizeof(buffer));
+    if(written == sizeof(buffer)) return 0;
+    if(written < 0) return written;
+    errno = ENOSPC;
+    return -1;
+}
+
+
+int do_dump(mesgfd, datafd, indexfd, outfd)
+int mesgfd, datafd, indexfd, outfd;
+{
+    int maxfd, nfound, size1, size2, eof1, eof2;
+    int rc;
+    fd_set readset, selectset;
+    struct timeval timeout;
+    int outpipe[2];
+    int header_done;   /* flag - header has been written */
+    char *indexfile_tmp = NULL;
+    char *indexfile_real = NULL;
+    char level_str[NUM_STR_SIZE];
+    char kb_str[NUM_STR_SIZE];
+    char kps_str[NUM_STR_SIZE];
+    char orig_kb_str[NUM_STR_SIZE];
+    char *fn;
+    char *q;
+    times_t runtime;
+    double dumptime;   /* Time dump took in secs */
+    int compresspid = -1, indexpid = -1, killerr;
+    char *errfname = NULL;
+
+#ifndef DUMPER_SOCKET_BUFFERING
+#define DUMPER_SOCKET_BUFFERING 0
+#endif
+
+#if !defined(SO_RCVBUF) || !defined(SO_RCVLOWAT)
+#undef  DUMPER_SOCKET_BUFFERING
+#define DUMPER_SOCKET_BUFFERING 0
+#endif
+
+#if DUMPER_SOCKET_BUFFERING
+    int lowat = NETWORK_BLOCK_BYTES;
+    int recbuf = 0;
+    int sizeof_recbuf = sizeof(recbuf);
+    int lowwatset = 0;
+    int lowwatset_count = 0;
+#endif
+
+    startclock();
+
+    datain = dataout = databuf;
+    datalimit = databuf + sizeof(databuf);
+    dumpsize = dumpbytes = origsize = filesize = dump_result = 0;
+    nb_header_block = 0;
+    got_info_endline = got_sizeline = got_endline = 0;
+    header_done = 0;
+    amfree(backup_name);
+    amfree(recover_cmd);
+    amfree(compress_suffix);
+
+    ap_snprintf(level_str, sizeof(level_str), "%d", level);
+    fn = sanitise_filename(diskname);
+    errfname = newvstralloc(errfname,
+                           AMANDA_TMPDIR,
+                           "/", hostname,
+                           ".", fn,
+                           ".", level_str,
+                           ".errout",
+                           NULL);
+    amfree(fn);
+    if((errf = fopen(errfname, "w+")) == NULL) {
+       errstr = newvstralloc(errstr,
+                             "errfile open \"", errfname, "\": ",
+                             strerror(errno),
+                             NULL);
+       amfree(errfname);
+       rc = 2;
+       goto failed;
+    }
+    unlink(errfname);                          /* so it goes away on close */
+    amfree(errfname);
+
+    /* insert pipe in the *READ* side, if server-side compression is desired */
+    compresspid = -1;
+    if (srvcompress) {
+       int tmpfd;
+
+       tmpfd = datafd;
+       pipe(outpipe); /* outpipe[0] is pipe's stdin, outpipe[1] is stdout. */
+       datafd = outpipe[0];
+       if(datafd < 0 || datafd >= FD_SETSIZE) {
+           aclose(outpipe[0]);
+           aclose(outpipe[1]);
+           errstr = newstralloc(errstr, "descriptor out of range");
+           errno = EMFILE;
+           rc = 2;
+           goto failed;
+       }
+       switch(compresspid=fork()) {
+       case -1:
+           errstr = newstralloc2(errstr, "couldn't fork: ", strerror(errno));
+           rc = 2;
+           goto failed;
+       default:
+           aclose(outpipe[1]);
+           aclose(tmpfd);
+           break;
+       case 0:
+           aclose(outpipe[0]);
+           /* child acts on stdin/stdout */
+           if (dup2(outpipe[1],1) == -1)
+               fprintf(stderr, "err dup2 out: %s\n", strerror(errno));
+           if (dup2(tmpfd, 0) == -1)
+               fprintf(stderr, "err dup2 in: %s\n", strerror(errno));
+           for(tmpfd = 3; tmpfd <= FD_SETSIZE; ++tmpfd) {
+               close(tmpfd);
+           }
+           /* now spawn gzip -1 to take care of the rest */
+           execlp(COMPRESS_PATH, COMPRESS_PATH,
+                  (srvcompress == srvcomp_best ? COMPRESS_BEST_OPT
+                                               : COMPRESS_FAST_OPT),
+                  (char *)0);
+           error("error: couldn't exec %s.\n", COMPRESS_PATH);
+       }
+       /* Now the pipe has been inserted. */
+    }
+
+    indexpid = -1;
+    if (indexfd != -1) {
+       int tmpfd;
+
+       indexfile_real = getindexfname(hostname, diskname, datestamp, level),
+       indexfile_tmp = stralloc2(indexfile_real, ".tmp");
+
+       if (mkpdir(indexfile_tmp, 02755, (uid_t)-1, (gid_t)-1) == -1) {
+          errstr = newvstralloc(errstr,
+                                "err create ",
+                                indexfile_tmp,
+                                ": ",
+                                strerror(errno),
+                                NULL);
+          amfree(indexfile_real);
+          amfree(indexfile_tmp);
+          rc = 2;
+          goto failed;
+       }
+
+       switch(indexpid=fork()) {
+       case -1:
+           errstr = newstralloc2(errstr, "couldn't fork: ", strerror(errno));
+           rc = 2;
+           goto failed;
+       default:
+           aclose(indexfd);
+           indexfd = -1;                       /* redundant */
+           break;
+       case 0:
+           if (dup2(indexfd, 0) == -1) {
+               error("err dup2 in: %s", strerror(errno));
+           }
+           indexfd = open(indexfile_tmp, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+           if (indexfd == -1)
+               error("err open %s: %s", indexfile_tmp, strerror(errno));
+           if (dup2(indexfd,1) == -1)
+               error("err dup2 out: %s", strerror(errno));
+           for(tmpfd = 3; tmpfd <= FD_SETSIZE; ++tmpfd) {
+               close(tmpfd);
+           }
+           execlp(COMPRESS_PATH, COMPRESS_PATH, COMPRESS_BEST_OPT, (char *)0);
+           error("error: couldn't exec %s.", COMPRESS_PATH);
+       }
+    }
+
+    NAUGHTY_BITS_INITIALIZE;
+
+    maxfd = max(mesgfd, datafd) + 1;
+    eof1 = eof2 = 0;
+
+    FD_ZERO(&readset);
+
+    /* Just process messages for now.  Once we have done the header
+    ** we will start processing data too.
+    */
+    FD_SET(mesgfd, &readset);
+
+    if(datafd == -1) eof1 = 1; /* fake eof on data */
+
+#if DUMPER_SOCKET_BUFFERING
+
+#ifndef EST_PACKET_SIZE
+#define EST_PACKET_SIZE        512
+#endif
+#ifndef        EST_MIN_WINDOW
+#define        EST_MIN_WINDOW  EST_PACKET_SIZE*4 /* leave room for 2k in transit */
+#endif
+
+    else {
+       recbuf = STREAM_BUFSIZE;
+       if (setsockopt(datafd, SOL_SOCKET, SO_RCVBUF,
+                      (void *) &recbuf, sizeof_recbuf)) {
+           const int errornumber = errno;
+           fprintf(stderr, "%s: pid %ld setsockopt(SO_RCVBUF): %s\n",
+                   get_pname(), (long) getpid(), strerror(errornumber));
+       }
+       if (getsockopt(datafd, SOL_SOCKET, SO_RCVBUF,
+                      (void *) &recbuf, (void *)&sizeof_recbuf)) {
+           const int errornumber = errno;
+           fprintf(stderr, "%s: pid %ld getsockopt(SO_RCVBUF): %s\n",
+                   get_pname(), (long) getpid(), strerror(errornumber));
+           recbuf = 0;
+       }
+
+       /* leave at least EST_MIN_WINDOW between lowwat and recbuf */
+       if (recbuf-lowat < EST_MIN_WINDOW)
+           lowat = recbuf-EST_MIN_WINDOW;
+
+       /* if lowwat < ~512, don't bother */
+       if (lowat < EST_PACKET_SIZE)
+           recbuf = 0;
+       fprintf(stderr, "%s: pid %ld receive size is %d, low water is %d\n",
+               get_pname(), (long) getpid(), recbuf, lowat);
+    }
+#endif
+
+    while(!(eof1 && eof2)) {
+
+#if DUMPER_SOCKET_BUFFERING
+       /* Set socket buffering */
+       if (recbuf>0 && !lowwatset) {
+           if (setsockopt(datafd, SOL_SOCKET, SO_RCVLOWAT,
+                          (void *) &lowat, sizeof(lowat))) {
+               const int errornumber = errno;
+               fprintf(stderr,
+                       "%s: pid %ld setsockopt(SO_RCVLOWAT): %s\n",
+                       get_pname(), (long) getpid(), strerror(errornumber));
+           }
+           lowwatset = 1;
+           lowwatset_count++;
+       }
+#endif
+
+       timeout.tv_sec = conf_dtimeout;
+       timeout.tv_usec = 0;
+       memcpy(&selectset, &readset, sizeof(fd_set));
+
+       nfound = select(maxfd, (SELECT_ARG_TYPE *)(&selectset), NULL, NULL, &timeout);
+
+       /* check for errors or timeout */
+
+#if DUMPER_SOCKET_BUFFERING
+       if (nfound==0 && lowwatset) {
+           const int zero = 0;
+           /* Disable socket buffering and ... */
+           if (setsockopt(datafd, SOL_SOCKET, SO_RCVLOWAT,
+                          (void *) &zero, sizeof(zero))) {
+               const int errornumber = errno;
+               fprintf(stderr,
+                       "%s: pid %ld setsockopt(SO_RCVLOWAT): %s\n",
+                       get_pname(), (long) getpid(), strerror(errornumber));
+           }
+           lowwatset = 0;
+
+           /* ... try once more */
+           timeout.tv_sec = conf_dtimeout;
+           timeout.tv_usec = 0;
+           memcpy(&selectset, &readset, sizeof(fd_set));
+           nfound = select(maxfd, (SELECT_ARG_TYPE *)(&selectset), NULL, NULL, &timeout);
+       }
+#endif
+
+       if(nfound == 0)  {
+           errstr = newstralloc(errstr, "data timeout");
+           rc = 2;
+           goto failed;
+       }
+       if(nfound == -1) {
+           errstr = newstralloc2(errstr, "select: ", strerror(errno));
+           rc = 2;
+           goto failed;
+       }
+
+       /* read/write any data */
+
+       if(datafd >= 0 && FD_ISSET(datafd, &selectset)) {
+           size1 = read(datafd, datain, datalimit - datain);
+           if(size1 < 0) {
+               errstr = newstralloc2(errstr, "data read: ", strerror(errno));
+               rc = 2;
+               goto failed;
+           }
+           if(update_dataptr(&outfd, size1)) {
+               rc = 2;
+               goto failed;
+           }
+           if(size1 == 0) {
+               eof1 = 1;
+               FD_CLR(datafd, &readset);
+               aclose(datafd);
+           }
+       }
+
+       if(mesgfd >= 0 && FD_ISSET(mesgfd, &selectset)) {
+           size2 = read(mesgfd, mesgbuf, sizeof(mesgbuf)-1);
+           switch(size2) {
+           case -1:
+               errstr = newstralloc2(errstr, "mesg read: ", strerror(errno));
+               rc = 2;
+               goto failed;
+           case 0:
+               eof2 = 1;
+               process_dumpeof();
+               FD_CLR(mesgfd, &readset);
+               aclose(mesgfd);
+               break;
+           default:
+               mesgbuf[size2] = '\0';
+               add_msg_data(mesgbuf, size2);
+           }
+
+           if (got_info_endline && !header_done) { /* time to do the header */
+               make_tapeheader(&file, F_DUMPFILE);
+               if (write_tapeheader(outfd, &file)) {
+                   int save_errno = errno;
+                   errstr = newstralloc2(errstr, "write_tapeheader: ", 
+                                         strerror(errno));
+                   if(save_errno == ENOSPC) {
+                       putresult(NO_ROOM, "%s %lu\n", handle, 
+                                 use+split_size-dumpsize);
+                       use = 0; /* force RQ_MORE_DISK */
+                       split_size = dumpsize;
+                       rc = 1;
+                   }
+                   else {
+                       rc = 2;
+                   }
+                   goto failed;
+               }
+               dumpsize += DISK_BLOCK_KB;
+               filesize += DISK_BLOCK_KB;
+               nb_header_block++;
+               header_done = 1;
+               strncat(cont_filename,filename,sizeof(cont_filename));
+               cont_filename[sizeof(cont_filename)-1] = '\0';
+
+               if (datafd != -1)
+                   FD_SET(datafd, &readset);   /* now we can read the data */
+           }
+       }
+    } /* end while */
+
+#if DUMPER_SOCKET_BUFFERING
+    if(lowwatset_count > 1) {
+       fprintf(stderr, "%s: pid %ld low water set %d times\n",
+               get_pname(), (long) getpid(), lowwatset_count);
+    }
+#endif
+
+    if(dump_result > 1) {
+       rc = 2;
+       goto failed;
+    }
+
+    runtime = stopclock();
+    dumptime = runtime.r.tv_sec + runtime.r.tv_usec/1000000.0;
+
+    dumpsize -= (nb_header_block * DISK_BLOCK_KB);/* don't count the header */
+    if (dumpsize < 0) dumpsize = 0;    /* XXX - maybe this should be fatal? */
+
+    ap_snprintf(kb_str, sizeof(kb_str), "%ld", dumpsize);
+    ap_snprintf(kps_str, sizeof(kps_str),
+               "%3.1f",
+               dumptime ? dumpsize / dumptime : 0.0);
+    ap_snprintf(orig_kb_str, sizeof(orig_kb_str), "%ld", origsize);
+    errstr = newvstralloc(errstr,
+                         "sec ", walltime_str(runtime),
+                         " ", "kb ", kb_str,
+                         " ", "kps ", kps_str,
+                         " ", "orig-kb ", orig_kb_str,
+                         NULL);
+    q = squotef("[%s]", errstr);
+    putresult(DONE, "%s %ld %ld %ld %s\n", handle, origsize, dumpsize,
+             (long)(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);
+
+       break;
+
+    case 1:
+       log_start_multiline();
+       log_add(L_STRANGE, "%s %s %d [%s]", hostname, diskname, level, errstr);
+       log_msgout(L_STRANGE);
+       log_end_multiline();
+
+       break;
+    }
+
+    if(errf) afclose(errf);
+
+    if (indexfile_tmp) {
+       waitpid(indexpid,NULL,0);
+       if(rename(indexfile_tmp, indexfile_real) != 0) {
+           log_add(L_WARNING, "could not rename \"%s\" to \"%s\": %s",
+                   indexfile_tmp, indexfile_real, strerror(errno));
+       }
+       amfree(indexfile_tmp);
+       amfree(indexfile_real);
+    }
+
+    return 0;
+
+ failed:
+
+#if DUMPER_SOCKET_BUFFERING
+    if(lowwatset_count > 1) {
+       fprintf(stderr, "%s: pid %ld low water set %d times\n",
+               get_pname(), (long) getpid(), lowwatset_count);
+    }
+#endif
+
+    if(!abort_pending) {
+       q = squotef("[%s]", errstr);
+       if(rc==2)
+           putresult(FAILED, "%s %s\n", handle, q);
+       else
+           putresult(TRYAGAIN, "%s %s\n", handle, q);
+       amfree(q);
+    }
+
+    /* kill all child process */
+    if(compresspid != -1) {
+       killerr = kill(compresspid,SIGTERM);
+       if(killerr == 0) {
+           fprintf(stderr,"%s: kill compress command\n",get_pname());
+       }
+       else if ( killerr == -1 ) {
+           if(errno != ESRCH)
+               fprintf(stderr,"%s: can't kill compress command: %s\n", 
+                              get_pname(), strerror(errno));
+       }
+    }
+
+    if(indexpid != -1) {
+       killerr = kill(indexpid,SIGTERM);
+       if(killerr == 0) {
+           fprintf(stderr,"%s: kill index command\n",get_pname());
+       }
+       else if ( killerr == -1 ) {
+           if(errno != ESRCH)
+               fprintf(stderr,"%s: can't kill index command: %s\n", 
+                              get_pname(),strerror(errno));
+       }
+    }
+
+    if(!abort_pending) {
+       log_start_multiline();
+       log_add(L_FAIL, "%s %s %s %d [%s]", hostname, diskname, 
+               datestamp, level, errstr);
+       if (errf) {
+           log_msgout(L_FAIL);
+       }
+       log_end_multiline();
+    }
+
+    if(errf) afclose(errf);
+
+    if (indexfile_tmp) {
+       unlink(indexfile_tmp);
+       amfree(indexfile_tmp);
+       amfree(indexfile_real);
+    }
+
+    return rc;
+}
+
+/* -------------------- */
+
+char *hostname, *disk;
+int response_error;
+
+void sendbackup_response(p, pkt)
+proto_t *p;
+pkt_t *pkt;
+{
+    int data_port = -1;
+    int mesg_port = -1;
+    int index_port = -1;
+    char *line;
+    char *fp;
+    char *s;
+    char *t;
+    int ch;
+    int tch;
+
+    am_release_feature_set(their_features);
+    their_features = NULL;
+
+    if(p->state == S_FAILED) {
+       if(pkt == NULL) {
+           if(p->prevstate == S_REPWAIT) {
+               errstr = newstralloc(errstr, "[reply timeout]");
+           }
+           else {
+               errstr = newstralloc(errstr, "[request timeout]");
+           }
+           response_error = 1;
+           return;
+       }
+    }
+
+#if 0
+    fprintf(stderr, "got %sresponse:\n----\n%s----\n\n",
+           (p->state == S_FAILED) ? "NAK " : "", pkt->body);
+#endif
+
+#ifdef KRB4_SECURITY
+    if(krb4_auth && !check_mutual_authenticator(&cred.session, pkt, p)) {
+       errstr = newstralloc(errstr, "mutual-authentication failed");
+       response_error = 2;
+       return;
+    }
+#endif
+
+    s = pkt->body;
+    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) {
+#undef sc
+
+#define sc "features="
+           t = strstr(line, sc);
+           if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
+               t += sizeof(sc)-1;
+#undef sc
+               am_release_feature_set(their_features);
+               if((their_features = am_string_to_feature(t)) == NULL) {
+                   errstr = newvstralloc(errstr,
+                                         "bad features value: ",
+                                         line,
+                                         NULL);
+               }
+           }
+
+           continue;
+       }
+
+#define sc "ERROR "
+       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+           t = line + sizeof(sc)-1;
+           tch = t[-1];
+#undef sc
+
+           fp = t - 1;
+           skip_whitespace(t, tch);
+           errstr = newvstralloc(errstr,
+                                 (p->state == S_FAILED) ? "nak error: " : "",
+                                 fp,
+                                 NULL);
+           response_error = ((p->state == S_FAILED) ? 1 : 2);
+           return;
+       }
+
+#define sc "CONNECT "
+       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+#undef sc
+
+#define sc "DATA "
+           t = strstr(line, sc);
+           if(t != NULL && isspace((int)t[-1])) {
+               t += sizeof(sc)-1;
+#undef sc
+               data_port = atoi(t);
+           }
+
+#define sc "MESG "
+           t = strstr(line, sc);
+           if(t != NULL && isspace((int)t[-1])) {
+               t += sizeof(sc)-1;
+#undef sc
+               mesg_port = atoi(t);
+           }
+
+#define sc "INDEX "
+           t = strstr(line, sc);
+           if(t != NULL && isspace((int)t[-1])) {
+               t += sizeof(sc)-1;
+#undef sc
+               index_port = atoi(t);
+           }
+           continue;
+       }
+
+       errstr = newvstralloc(errstr,
+                             "unknown response: ",
+                             line,
+                             NULL);
+       response_error = 2;
+       return;
+    }
+
+    if (data_port == -1 || mesg_port == -1) {
+       errstr = newvstralloc(errstr, "bad CONNECT response", NULL);
+       response_error = 2;
+       return;
+    }
+
+    datafd = stream_client(hostname, data_port, -1, -1, NULL);
+    if(datafd == -1) {
+       errstr = newvstralloc(errstr,
+                             "could not connect to data port: ",
+                             strerror(errno),
+                             NULL);
+       response_error = 1;
+       return;
+    }
+    mesgfd = stream_client(hostname, mesg_port, -1, -1, NULL);
+    if(mesgfd == -1) {
+       errstr = newvstralloc(errstr,
+                             "could not connect to mesg port: ",
+                             strerror(errno),
+                             NULL);
+       aclose(datafd);
+       datafd = -1;                            /* redundant */
+       response_error = 1;
+       return;
+    }
+
+    if (index_port != -1) {
+       indexfd = stream_client(hostname, index_port, -1, -1, NULL);
+       if (indexfd == -1) {
+           errstr = newvstralloc(errstr,
+                                 "could not connect to index port: ",
+                                 strerror(errno),
+                                 NULL);
+           aclose(datafd);
+           aclose(mesgfd);
+           datafd = mesgfd = -1;               /* redundant */
+           response_error = 1;
+           return;
+       }
+    }
+
+    /* everything worked */
+
+#ifdef KRB4_SECURITY
+    if(krb4_auth && kerberos_handshake(datafd, cred.session) == 0) {
+       errstr = newstralloc(errstr,
+                            "mutual authentication in data stream failed");
+       aclose(datafd);
+       aclose(mesgfd);
+       if (indexfd != -1)
+           aclose(indexfd);
+       response_error = 1;
+       return;
+    }
+    if(krb4_auth && kerberos_handshake(mesgfd, cred.session) == 0) {
+       errstr = newstralloc(errstr,
+                            "mutual authentication in mesg stream failed");
+       aclose(datafd);
+       if (indexfd != -1)
+           aclose(indexfd);
+       aclose(mesgfd);
+       response_error = 1;
+       return;
+    }
+#endif
+    response_error = 0;
+    return;
+}
+
+int startup_dump(hostname, disk, device, level, dumpdate, progname, options)
+char *hostname, *disk, *device, *dumpdate, *progname, *options;
+int level;
+{
+    char level_string[NUM_STR_SIZE];
+    char *req = NULL;
+    int rc;
+
+    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);
+
+    ap_snprintf(level_string, sizeof(level_string), "%d", level);
+    req = vstralloc("SERVICE sendbackup\n",
+                   "OPTIONS ",
+                   has_features ? "features=" : "",
+                   has_features ? our_feature_string : "",
+                   has_features ? ";" : "",
+                   has_hostname ? "hostname=" : "",
+                   has_hostname ? hostname : "",
+                   has_hostname ? ";" : "",
+                   "\n",
+                   progname,
+                   " ", disk,
+                   " ", device && has_device ? device : "",
+                   " ", level_string,
+                   " ", dumpdate,
+                   " ", "OPTIONS ", options,
+                   "\n",
+                   NULL);
+
+    datafd = mesgfd = indexfd = -1;
+
+#ifdef KRB4_SECURITY
+    if(krb4_auth) {
+       char rc_str[NUM_STR_SIZE];
+
+       rc = make_krb_request(hostname, kamanda_port, req, NULL,
+                             STARTUP_TIMEOUT, sendbackup_response);
+       if(!rc) {
+           char inst[256], realm[256];
+#define HOSTNAME_INSTANCE inst
+           /*
+            * This repeats a lot of work with make_krb_request, but it's
+            * ultimately the kerberos library's fault: krb_mk_req calls
+            * krb_get_cred, but doesn't make the session key available!
+            * XXX: But admittedly, we could restructure a bit here and
+            * at least eliminate the duplicate gethostbyname().
+            */
+           if(host2krbname(hostname, inst, realm) == 0)
+               rc = -1;
+           else
+               rc = krb_get_cred(CLIENT_HOST_PRINCIPLE, CLIENT_HOST_INSTANCE,
+                                 realm, &cred);
+           if(rc > 0 ) {
+               ap_snprintf(rc_str, sizeof(rc_str), "%d", rc);
+               errstr = newvstralloc(errstr,
+                                     "[host ", hostname,
+                                     ": krb4 error (krb_get_cred) ",
+                                     rc_str,
+                                     ": ", krb_err_txt[rc],
+                                     NULL);
+               amfree(req);
+               return 2;
+           }
+       }
+       if(rc > 0) {
+           ap_snprintf(rc_str, sizeof(rc_str), "%d", rc);
+           errstr = newvstralloc(errstr,
+                                 "[host ", hostname,
+                                 ": krb4 error (make_krb_req) ",
+                                 rc_str,
+                                 ": ", krb_err_txt[rc],
+                                 NULL);
+           amfree(req);
+           return 2;
+       }
+    } else
+#endif
+       rc = make_request(hostname, amanda_port, req, NULL,
+                         STARTUP_TIMEOUT, sendbackup_response);
+
+    req = NULL;                                        /* do not own this any more */
+
+    if(rc) {
+       errstr = newvstralloc(errstr,
+                             "[could not resolve name \"", hostname, "\"]",
+                             NULL);
+       return 2;
+    }
+    run_protocol();
+    return response_error;
+}
diff --git a/server-src/find.c b/server-src/find.c
new file mode 100644 (file)
index 0000000..61c279b
--- /dev/null
@@ -0,0 +1,721 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: find.c,v 1.6.2.4.4.2.2.5 2003/10/27 18:33:03 martinea Exp $
+ *
+ * controlling process for the Amanda backup system
+ */
+#include "amanda.h"
+#include "conffile.h"
+#include "tapefile.h"
+#include "logfile.h"
+#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));
+char *find_nicedate P((int datestamp));
+
+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;
+{
+    char *conf_logdir, *logfile = NULL;
+    int tape, maxtape, seq, logs;
+    tape_t *tp;
+    find_result_t *output_find = NULL;
+
+    dynamic_disklist = dyna_disklist;
+    find_diskqp = diskqp;
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+       conf_logdir = stralloc(conf_logdir);
+    } else {
+       conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    maxtape = lookup_nb_tape();
+
+    for(tape = 1; tape <= maxtape; tape++) {
+       char ds_str[NUM_STR_SIZE];
+
+       tp = lookup_tapepos(tape);
+       if(tp == NULL) continue;
+       ap_snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
+
+       /* search log files */
+
+       logs = 0;
+
+       /* new-style log.<date>.<seq> */
+
+       for(seq = 0; 1; seq++) {
+           char seq_str[NUM_STR_SIZE];
+
+           ap_snprintf(seq_str, sizeof(seq_str), "%d", seq);
+           logfile = newvstralloc(logfile,
+                       conf_logdir, "/log.", ds_str, ".", seq_str, NULL);
+           if(access(logfile, R_OK) != 0) break;
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, seq, logfile);
+       }
+
+       /* search old-style amflush log, if any */
+
+       logfile = newvstralloc(logfile,
+                              conf_logdir, "/log.", ds_str, ".amflush", NULL);
+       if(access(logfile,R_OK) == 0) {
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, 1000, logfile);
+       }
+
+       /* search old-style main log, if any */
+
+       logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+       if(access(logfile,R_OK) == 0) {
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, -1, logfile);
+       }
+       if(logs == 0 && tp->datestamp != 0)
+           printf("Warning: no log files found for tape %s written %s\n",
+                  tp->label, find_nicedate(tp->datestamp));
+    }
+    amfree(logfile);
+    amfree(conf_logdir);
+
+    search_holding_disk(&output_find);
+    return(output_find);
+}
+
+char **find_log()
+{
+    char *conf_logdir, *logfile = NULL;
+    int tape, maxtape, seq, logs;
+    tape_t *tp;
+    char **output_find_log = NULL;
+    char **current_log;
+
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+       conf_logdir = stralloc(conf_logdir);
+    } else {
+       conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    maxtape = lookup_nb_tape();
+
+    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;
+       ap_snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
+
+       /* search log files */
+
+       logs = 0;
+
+       /* new-style log.<date>.<seq> */
+
+       for(seq = 0; 1; seq++) {
+           char seq_str[NUM_STR_SIZE];
+
+           ap_snprintf(seq_str, sizeof(seq_str), "%d", seq);
+           logfile = newvstralloc(logfile,
+                       conf_logdir, "/log.", ds_str, ".", 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);
+               current_log++;
+               logs++;
+               break;
+           }
+       }
+
+       /* search old-style amflush log, if any */
+
+       logfile = newvstralloc(logfile,
+                              conf_logdir, "/log.", ds_str, ".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);
+               current_log++;
+               logs++;
+           }
+       }
+
+       /* search old-style main log, if any */
+
+       logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+       if(access(logfile,R_OK) == 0) {
+           if(search_logfile(NULL, tp->label, tp->datestamp, -1, logfile)) {
+               *current_log = vstralloc("log.", ds_str, NULL);
+               current_log++;
+               logs++;
+           }
+       }
+       if(logs == 0 && tp->datestamp != 0)
+           printf("Warning: no log files found for tape %s written %s\n",
+                  tp->label, find_nicedate(tp->datestamp));
+    }
+    amfree(logfile);
+    amfree(conf_logdir);
+    *current_log = NULL;
+    return(output_find_log);
+}
+
+void search_holding_disk(output_find)
+find_result_t **output_find;
+{
+    holdingdisk_t *hdisk;
+    sl_t  *holding_list;
+    sle_t *dir;
+    char *sdirname = NULL;
+    char *destname = NULL;
+    char *hostname = NULL;
+    char *diskname = NULL;
+    DIR *workdir;
+    struct dirent *entry;
+    int level;
+    disk_t *dp;
+
+    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,
+                                   NULL);
+           if((workdir = opendir(sdirname)) == NULL) {
+               continue;
+           }
+
+           while((entry = readdir(workdir)) != NULL) {
+               if(is_dot_or_dotdot(entry->d_name)) {
+                   continue;
+               }
+               destname = newvstralloc(destname,
+                                       sdirname, "/", entry->d_name,
+                                       NULL);
+               if(is_emptyfile(destname)) {
+                   continue;
+               }
+               amfree(hostname);
+               amfree(diskname);
+               if(get_amanda_names(destname, &hostname, &diskname, &level) != F_DUMPFILE) {
+                   continue;
+               }
+               if(level < 0 || level > 9)
+                   continue;
+
+               dp = NULL;
+               for(;;) {
+                   char *s;
+                   if((dp = lookup_disk(hostname, diskname)))
+                       break;
+                   if((s = strrchr(hostname,'.')) == NULL)
+                       break;
+                   *s = '\0';
+               }
+               if ( dp == NULL ) {
+                   continue;
+               }
+
+               if(find_match(hostname,diskname)) {
+                   find_result_t *new_output_find =
+                       alloc(sizeof(find_result_t));
+                   new_output_find->next=*output_find;
+                   new_output_find->datestamp=atoi(dir->name);
+                   new_output_find->datestamp_aux=1001;
+                   new_output_find->hostname=hostname;
+                   hostname = NULL;
+                   new_output_find->diskname=diskname;
+                   diskname = NULL;
+                   new_output_find->level=level;
+                   new_output_find->label=stralloc(destname);
+                   new_output_find->filenum=0;
+                   new_output_find->status=stralloc("OK");
+                   *output_find=new_output_find;
+               }
+           }
+           closedir(workdir);
+       }       
+    }
+    free_sl(holding_list);
+    holding_list = NULL;
+    amfree(destname);
+    amfree(sdirname);
+    amfree(hostname);
+    amfree(diskname);
+}
+
+static int find_compare(i1, j1)
+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;
+
+    for(k=0;k<nb_compare;k++) {
+       switch (find_sort_order[k]) {
+       case 'h' : compare=strcmp((*i)->hostname,(*j)->hostname);
+                  break;
+       case 'H' : compare=strcmp((*j)->hostname,(*i)->hostname);
+                  break;
+       case 'k' : compare=strcmp((*i)->diskname,(*j)->diskname);
+                  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;
+                  break;
+       case 'D' : compare=(*j)->datestamp - (*i)->datestamp;
+                  if (compare == 0)
+                       compare = (*j)->datestamp_aux - (*i)->datestamp_aux;
+                  break;
+       case 'l' : compare=(*j)->level - (*i)->level;
+                  break;
+       case 'L' : compare=(*i)->level - (*j)->level;
+                  break;
+       case 'b' : compare=strcmp((*i)->label,(*j)->label);
+                  break;
+       case 'B' : compare=strcmp((*j)->label,(*i)->label);
+                  break;
+       }
+       if(compare != 0)
+           return compare;
+    }
+    return 0;
+}
+
+void sort_find_result(sort_order, output_find)
+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;
+
+    find_sort_order = sort_order;
+    /* qsort core dump if nothing to sort */
+    if(*output_find==NULL)
+       return;
+
+    /* How many result */
+    for(output_find_result=*output_find;
+       output_find_result;
+       output_find_result=output_find_result->next) {
+       nb_result++;
+    }
+
+    /* put the list in an array */
+    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++) {
+       array_find_result[no_result]=output_find_result;
+    }
+
+    /* sort the array */
+    qsort(array_find_result,nb_result,sizeof(find_result_t *),
+         find_compare);
+
+    /* put the sorted result in the list */
+    for(no_result=0;
+       no_result<nb_result-1; no_result++) {
+       array_find_result[no_result]->next = array_find_result[no_result+1];
+    }
+    array_find_result[nb_result-1]->next=NULL;
+    *output_find=array_find_result[0];
+    amfree(array_find_result);
+}
+
+void print_find_result(output_find)
+find_result_t *output_find;
+{
+    find_result_t *output_find_result;
+    int max_len_datestamp = 4;
+    int max_len_hostname  = 4;
+    int max_len_diskname  = 4;
+    int max_len_level     = 2;
+    int max_len_label     =12;
+    int max_len_filenum   = 4;
+    int max_len_status    = 6;
+    int 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(output_find_result->hostname);
+       if(len>max_len_hostname) max_len_hostname=len;
+
+       len=strlen(output_find_result->diskname);
+       if(len>max_len_diskname) max_len_diskname=len;
+
+       len=strlen(output_find_result->label);
+       if(len>max_len_label) max_len_label=len;
+
+       len=strlen(output_find_result->status);
+       if(len>max_len_status) max_len_status=len;
+    }
+
+    /*
+     * Since status is the rightmost field, we zap the maximum length
+     * because it is not needed.  The code is left in place in case
+     * another column is added later.
+     */
+    max_len_status = 1;
+
+    if(output_find==NULL) {
+       printf("\nNo dump to list\n");
+    }
+    else {
+       printf("\ndate%*s host%*s disk%*s lv%*s tape or file%*s file%*s status\n",
+              max_len_datestamp-4,"",
+              max_len_hostname-4 ,"",
+              max_len_diskname-4 ,"",
+              max_len_level-2    ,"",
+              max_len_label-12   ,"",
+              max_len_filenum-4  ,"");
+        for(output_find_result=output_find;
+               output_find_result;
+               output_find_result=output_find_result->next) {
+
+           printf("%-*s %-*s %-*s %*d %-*s %*d %-*s\n",
+                   max_len_datestamp, 
+                       find_nicedate(output_find_result->datestamp),
+                   max_len_hostname,  output_find_result->hostname,
+                   max_len_diskname,  output_find_result->diskname,
+                   max_len_level,     output_find_result->level,
+                   max_len_label,     output_find_result->label,
+                   max_len_filenum,   output_find_result->filenum,
+                   max_len_status,    output_find_result->status);
+       }
+    }
+}
+
+void free_find_result(output_find)
+find_result_t **output_find;
+{
+    find_result_t *output_find_result, *prev;
+
+    prev=NULL;
+    for(output_find_result=*output_find;
+           output_find_result;
+           output_find_result=output_find_result->next) {
+       if(prev != NULL) amfree(prev);
+       amfree(output_find_result->hostname);
+       amfree(output_find_result->diskname);
+       amfree(output_find_result->label);
+       amfree(output_find_result->status);
+       prev = output_find_result;
+    }
+    if(prev != NULL) amfree(prev);
+    output_find = NULL;
+}
+
+int find_match(host, disk)
+char *host, *disk;
+{
+    disk_t *dp = lookup_disk(host,disk);
+    return (dp && dp->todo);
+}
+
+char *find_nicedate(datestamp)
+int datestamp;
+{
+    static char nice[20];
+    int year, month, day;
+
+    year  = datestamp / 10000;
+    month = (datestamp / 100) % 100;
+    day   = datestamp % 100;
+
+    ap_snprintf(nice, sizeof(nice), "%4d-%02d-%02d", year, month, day);
+
+    return nice;
+}
+
+static int parse_taper_datestamp_log(logline, datestamp, label)
+char *logline;
+int *datestamp;
+char **label;
+{
+    char *s;
+    int ch;
+
+    s = logline;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       return 0;
+    }
+#define sc "datestamp"
+    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       return 0;
+    }
+    s += sizeof(sc)-1;
+    ch = s[-1];
+#undef sc
+
+    skip_whitespace(s, ch);
+    if(ch == '\0' || sscanf(s - 1, "%d", datestamp) != 1) {
+       return 0;
+    }
+    skip_integer(s, ch);
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       return 0;
+    }
+#define sc "label"
+    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+       return 0;
+    }
+    s += sizeof(sc)-1;
+    ch = s[-1];
+#undef sc
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       return 0;
+    }
+    *label = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    return 1;
+}
+
+/* if output_find is NULL                                      */
+/*     return 1 if this is the logfile for this label          */
+/*     return 0 if this is not the logfile for this label      */
+/* 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;
+{
+    FILE *logf;
+    char *host, *host_undo;
+    char *disk, *disk_undo;
+    int   datestampI;
+    char *rest;
+    char *ck_label;
+    int level, filenum, ck_datestamp, tapematch;
+    int passlabel, ck_datestamp2;
+    char *s;
+    int ch;
+    disk_t *dp;
+
+    if((logf = fopen(logfile, "r")) == NULL)
+       error("could not open logfile %s: %s", logfile, strerror(errno));
+
+    /* check that this log file corresponds to the right tape */
+    tapematch = 0;
+    while(!tapematch && get_logline(logf)) {
+       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
+                     && strcmp(ck_label, label) == 0) {
+               tapematch = 1;
+           }
+       }
+    }
+
+    if(output_find == NULL) {
+       afclose(logf);
+        if(tapematch == 0)
+           return 0;
+       else
+           return 1;
+    }
+
+    if(tapematch == 0) {
+       afclose(logf);
+       return 0;
+    }
+
+    filenum = 0;
+    passlabel = 1;
+    while(get_logline(logf) && passlabel) {
+       if(curlog == L_SUCCESS && curprog == P_TAPER && passlabel) filenum++;
+       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);
+           } else if (strcmp(ck_label, label)) {
+               passlabel = !passlabel;
+           }
+       }
+       if(curlog == L_SUCCESS || curlog == L_FAIL) {
+           s = curstr;
+           ch = *s++;
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               printf("strange log line \"%s\"\n", curstr);
+               continue;
+           }
+           host = s - 1;
+           skip_non_whitespace(s, ch);
+           host_undo = s - 1;
+           *host_undo = '\0';
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               printf("strange log line \"%s\"\n", curstr);
+               continue;
+           }
+           disk = s - 1;
+           skip_non_whitespace(s, ch);
+           disk_undo = s - 1;
+           *disk_undo = '\0';
+
+           skip_whitespace(s, ch);
+           if(ch == '\0' || sscanf(s - 1, "%d", &datestampI) != 1) {
+               printf("strange log line \"%s\"\n", curstr);
+               continue;
+           }
+           skip_integer(s, ch);
+
+           if(datestampI < 100)  { /* old log didn't have datestamp */
+               level = datestampI;
+               datestampI = datestamp;
+           }
+           else {
+               skip_whitespace(s, ch);
+               if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+                   printf("strange log line \"%s\"\n", curstr);
+                   continue;
+               }
+               skip_integer(s, ch);
+           }
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               printf("strange log line \"%s\"\n", curstr);
+               continue;
+           }
+           rest = s - 1;
+           if((s = strchr(s, '\n')) != NULL) {
+               *s = '\0';
+           }
+
+           dp = lookup_disk(host,disk);
+           if ( dp == NULL ) {
+               if (dynamic_disklist == 0) {
+                   continue;
+               }
+               dp = add_disk(host, disk);
+               enqueue_disk(find_diskqp , dp);
+           }
+           if(find_match(host, disk)) {
+               if(curprog == P_TAPER) {
+                   find_result_t *new_output_find =
+                       (find_result_t *)alloc(sizeof(find_result_t));
+                   new_output_find->next=*output_find;
+                   new_output_find->datestamp=datestampI;
+                   new_output_find->datestamp_aux=datestamp_aux;
+                   new_output_find->hostname=stralloc(host);
+                   new_output_find->diskname=stralloc(disk);
+                   new_output_find->level=level;
+                   new_output_find->label=stralloc(label);
+                   new_output_find->filenum=filenum;
+                   if(curlog == L_SUCCESS) 
+                       new_output_find->status=stralloc("OK");
+                   else
+                       new_output_find->status=stralloc(rest);
+                   *output_find=new_output_find;
+               }
+               else if(curlog == L_FAIL) {     /* print other failures too */
+                   find_result_t *new_output_find =
+                       (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->hostname=stralloc(host);
+                   new_output_find->diskname=stralloc(disk);
+                   new_output_find->level=level;
+                   new_output_find->label=stralloc("---");
+                   new_output_find->filenum=0;
+                   new_output_find->status=vstralloc(
+                        "FAILED (",
+                        program_str[(int)curprog],
+                        ") ",
+                        rest,
+                        NULL);
+                   *output_find=new_output_find;
+               }
+           }
+       }
+    }
+    afclose(logf);
+    return 1;
+}
+
+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 *output_find_result;
+
+    for(output_find_result=output_find;
+       output_find_result;
+       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 &&
+           output_find_result->level == level) {
+
+           return output_find_result;
+       }
+    }
+    return(NULL);
+}
diff --git a/server-src/find.h b/server-src/find.h
new file mode 100644 (file)
index 0000000..779964b
--- /dev/null
@@ -0,0 +1,24 @@
+
+#define DEFAULT_SORT_ORDER      "hkdlb"
+
+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 *hostname;
+    char *diskname;
+    int level;
+    char *label;
+    int  filenum;
+    char *status;
+} find_result_t;
+
+find_result_t *find_dump P((int dyna_disklist, disklist_t* diskqp));
+char **find_log P(());
+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));
+
diff --git a/server-src/getconf.c b/server-src/getconf.c
new file mode 100644 (file)
index 0000000..dd0e8b0
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: getconf.c,v 1.8.4.2.2.2.2.4 2003/12/16 22:36:45 martinea Exp $
+ *
+ * a little wrapper to extract config variables for shell scripts
+ */
+#include "amanda.h"
+#include "version.h"
+#include "genversion.h"
+#include "conffile.h"
+
+#define HOSTNAME_INSTANCE "host_inst"
+
+int main P((int argc, char **argv));
+
+static struct build_info {
+    char *symbol;
+    char *value;
+} build_info[] = {
+    { "VERSION",                       "" },   /* must be [0] */
+    { "AMANDA_DEBUG_DAYS",             "" },   /* must be [1] */
+    { "TICKET_LIFETIME",               "" },   /* must be [2] */
+
+    { "bindir",                                bindir },
+    { "sbindir",                       sbindir },
+    { "libexecdir",                    libexecdir },
+    { "mandir",                                mandir },
+    { "AMANDA_TMPDIR",                 AMANDA_TMPDIR },
+    { "CONFIG_DIR",                    CONFIG_DIR },
+    { "MAILER",                                MAILER },
+    { "DEFAULT_SERVER",                        DEFAULT_SERVER },
+    { "DEFAULT_CONFIG",                        DEFAULT_CONFIG },
+    { "DEFAULT_TAPE_SERVER",           DEFAULT_TAPE_SERVER },
+    { "DEFAULT_TAPE_DEVICE",           DEFAULT_TAPE_SERVER },
+
+    { "BUILT_DATE",
+#if defined(BUILT_DATE)
+       BUILT_DATE
+#endif
+    },
+    { "BUILT_MACH",
+#if defined(BUILT_MACH)
+       BUILT_MACH
+#endif
+    },
+    { "CC",
+#if defined(CC)
+       CC
+#endif
+    },
+
+    { "AMANDA_DBGDIR",
+#if defined(AMANDA_DBGDIR)
+       AMANDA_DBGDIR
+#endif
+    },
+    { "DEV_PREFIX",
+#if defined(DEV_PREFIX)
+       DEV_PREFIX
+#endif
+    },
+    { "RDEV_PREFIX",
+#if defined(RDEV_PREFIX)
+       RDEV_PREFIX },
+#endif
+    { "DUMP",
+#if defined(DUMP)
+       DUMP
+#endif
+    },
+    { "RESTORE",
+#if defined(DUMP)
+       RESTORE
+#endif
+    },
+    { "VDUMP",
+#if defined(VDUMP)
+       VDUMP
+#endif
+    },
+    { "VRESTORE",
+#if defined(VDUMP)
+       VRESTORE
+#endif
+    },
+    { "XFSDUMP",
+#if defined(XFSDUMP)
+       XFSDUMP
+#endif
+    },
+    { "XFSRESTORE",
+#if defined(XFSDUMP)
+       XFSRESTORE
+#endif
+    },
+    { "VXDUMP",
+#if defined(VXDUMP)
+       VXDUMP
+#endif
+    },
+    { "VXRESTORE",
+#if defined(VXDUMP)
+       VXRESTORE
+#endif
+    },
+    { "SAMBA_CLIENT",
+#if defined(SAMBA_CLIENT)
+       SAMBA_CLIENT
+#endif
+    },
+    { "GNUTAR",
+#if defined(GNUTAR)
+       GNUTAR
+#endif
+    },
+    { "COMPRESS_PATH",
+#if defined(COMPRESS_PATH)
+       COMPRESS_PATH
+#endif
+    },
+    { "UNCOMPRESS_PATH",
+#if defined(UNCOMPRESS_PATH)
+       UNCOMPRESS_PATH
+#endif
+    },
+    { "listed_incr_dir",
+#if defined(GNUTAR_LISTED_INCREMENTAL_DIR)
+       GNUTAR_LISTED_INCREMENTAL_DIR
+#endif
+    },
+    { "GNUTAR_LISTED_INCREMENTAL_DIR",
+#if defined(GNUTAR_LISTED_INCREMENTAL_DIR)
+       GNUTAR_LISTED_INCREMENTAL_DIR
+#endif
+    },
+
+    { "AIX_BACKUP",
+#if defined(AIX_BACKUP)
+       "1"
+#endif
+    },
+    { "AIX_TAPEIO",
+#if defined(AIX_TAPEIO)
+       "1"
+#endif
+    },
+    { "DUMP_RETURNS_1",
+#if defined(DUMP_RETURNS_1)
+       "1"
+#endif
+    },
+
+    { "LOCKING",
+#if defined(USE_POSIX_FCNTL)
+       "POSIX_FCNTL"
+#elif defined(USE_FLOCK)
+       "FLOCK"
+#elif defined(USE_LOCKF)
+       "LOCKF"
+#elif defined(USE_LNLOCK)
+       "LNLOCK"
+#else
+       "NONE"
+#endif
+    },
+
+    { "STATFS_BSD",
+#if defined(STATFS_BSD)
+       "1"
+#endif
+    },
+    { "STATFS_OSF1",
+#if defined(STATFS_OSF1)
+       "1"
+#endif
+    },
+    { "STATFS_ULTRIX",
+#if defined(STATFS_ULTRIX)
+       "1"
+#endif
+    },
+    { "ASSERTIONS",
+#if defined(ASSERTIONS)
+       "1"
+#endif
+    },
+    { "DEBUG_CODE",
+#if defined(DEBUG_CODE)
+       "1"
+#endif
+    },
+    { "BSD_SECURITY",
+#if defined(BSD_SECURITY)
+       "1"
+#endif
+    },
+    { "USE_AMANDAHOSTS",
+#if defined(USE_AMANDAHOSTS)
+       "1"
+#endif
+    },
+    { "USE_RUNDUMP",
+#if defined(USE_RUNDUMP)
+       "1"
+#endif
+    },
+    { "FORCE_USERID",
+#if defined(FORCE_USERID)
+       "1"
+#endif
+    },
+    { "USE_VERSION_SUFFIXES",
+#if defined(USE_VERSION_SUFFIXES)
+       "1"
+#endif
+    },
+    { "HAVE_GZIP",
+#if defined(HAVE_GZIP)
+       "1"
+#endif
+    },
+
+    { "KRB4_SECURITY",
+#if defined(KRB4_SECURITY)
+       "1"
+#endif
+    },
+    { "SERVER_HOST_PRINCIPLE",
+#if defined(KRB4_SECURITY)
+       SERVER_HOST_PRINCIPLE
+#endif
+    },
+    { "SERVER_HOST_INSTANCE",
+#if defined(KRB4_SECURITY)
+       SERVER_HOST_INSTANCE
+#endif
+    },
+    { "SERVER_HOST_KEY_FILE",
+#if defined(KRB4_SECURITY)
+       SERVER_HOST_KEY_FILE
+#endif
+    },
+    { "CLIENT_HOST_PRINCIPLE",
+#if defined(KRB4_SECURITY)
+       CLIENT_HOST_PRINCIPLE
+#endif
+    },
+    { "CLIENT_HOST_INSTANCE",
+#if defined(KRB4_SECURITY)
+       CLIENT_HOST_INSTANCE
+#endif
+    },
+    { "CLIENT_HOST_KEY_FILE",
+#if defined(KRB4_SECURITY)
+       CLIENT_HOST_KEY_FILE
+#endif
+    },
+
+    { "COMPRESS_SUFFIX",
+#if defined(COMPRESS_SUFFIX)
+       COMPRESS_SUFFIX
+#endif
+    },
+    { "COMPRESS_FAST_OPT",
+#if defined(COMPRESS_FAST_OPT)
+       COMPRESS_FAST_OPT
+#endif
+    },
+    { "COMPRESS_BEST_OPT",
+#if defined(COMPRESS_BEST_OPT)
+       COMPRESS_BEST_OPT
+#endif
+    },
+    { "UNCOMPRESS_OPT",
+#if defined(UNCOMPRESS_OPT)
+       UNCOMPRESS_OPT
+#endif
+    },
+
+    { NULL,                    NULL }
+};
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    char *result;
+    int fd;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    char *pgm;
+    char *conffile;
+    char *parmname;
+    int i;
+    char number[NUM_STR_SIZE];
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    if((pgm = strrchr(argv[0], '/')) == NULL) {
+       pgm = argv[0];
+    } else {
+       pgm++;
+    }
+    set_pname(pgm);
+
+    if(argc < 2) {
+       fprintf(stderr, "Usage: %s [config] <parmname>\n", pgm);
+       exit(1);
+    }
+
+    if (argc > 2) {
+       config_name = stralloc(argv[1]);
+       config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+       parmname = argv[2];
+    } else {
+       char my_cwd[STR_SIZE];
+
+       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+           error("cannot determine current working directory");
+       }
+       config_dir = stralloc2(my_cwd, "/");
+       if ((config_name = strrchr(my_cwd, '/')) != NULL) {
+           config_name = stralloc(config_name + 1);
+       }
+       parmname = argv[1];
+    }
+
+    safe_cd();
+
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if(read_conffile(conffile)) {
+       error("errors processing config file \"%s\"", conffile);
+    }
+    amfree(conffile);
+
+    /*
+     * Fill in the build values that need runtime help.
+     */
+    build_info[0].value = stralloc(version());
+#if defined(AMANDA_DEBUG_DAYS)
+    i = AMANDA_DEBUG_DAYS;
+#else
+    i = -1;
+#endif
+    ap_snprintf(number, sizeof(number), "%ld", (long)i);
+    build_info[1].value = stralloc(number);
+#if defined(KRB4_SECURITY)
+    i = TICKET_LIFETIME;
+#else
+    i = -1;
+#endif
+    ap_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) {
+       char *s;
+       char *t;
+
+       t = stralloc(parmname + sizeof(p) - 1);
+       for(i = 0; (s = build_info[i].symbol) != NULL; i++) {
+           if(strcasecmp(s, t) == 0) {
+               break;
+           }
+       }
+       if(s == NULL) {
+           result = NULL;
+       } else {
+           result = build_info[i].value;
+           result = stralloc(result ? result : "");
+       }
+
+#undef p
+#define        p       "dbopen."
+
+    } 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;
+       } else {
+           pname++;
+       }
+       set_pname(pname);
+       dbopen();
+       if((dbname = dbfn()) == NULL) {
+           result = stralloc("/dev/null");
+       } else {
+           result = stralloc(dbname);
+       }
+
+#undef p
+#define        p       "dbclose."
+
+    } else if(strncmp(parmname, p, sizeof(p) - 1) == 0) {
+       char *t;
+       char *pname;
+       char *dbname;
+       int old_fd2;
+       int new_fd2;
+
+       t = stralloc(parmname + sizeof(p) - 1);
+       if((dbname = strchr(t, ':')) == NULL) {
+           error("cannot parse %s", parmname);
+       }
+       *dbname++ = '\0';
+       if((pname = strrchr(t, '/')) == NULL) {
+           pname = t;
+       } else {
+           pname++;
+       }
+       fflush(stderr);
+       if((old_fd2 = dup(2)) < 0) {
+           error("cannot dup2 fd2");
+       }
+       close(2);
+       if((new_fd2 = open(dbname, O_RDWR|O_APPEND, 0600)) != 2) {
+           int save_errno = errno;
+           FILE *f;
+
+           if((f = fdopen(old_fd2, "a")) == NULL) {
+               /* give up */
+               return 3;
+           }
+           fprintf(f, "%s: cannot open %s: ", get_pname(), dbname);
+           if(new_fd2 < 0) {
+               fputs(strerror(save_errno), f);
+           } else {
+               fprintf(f, "got %d instead of 2", new_fd2);
+           }
+           fputc('\n', f);
+           fclose(f);
+       }
+       /*
+        * Because we have not called dbopen(), dbclose() will write the
+        * end line to stderr, which we just redirected to the file on
+        * the command line.
+        */
+       set_pname(pname);
+       dbclose();
+       result = stralloc(dbname);
+       amfree(t);
+
+    } else {
+       result = getconf_byname(parmname);
+    }
+    if(result == NULL) {
+       result = stralloc("BUGGY");
+       fprintf(stderr, "%s: no such parameter \"%s\"\n",
+               get_pname(), parmname);
+       fflush(stderr);
+    }
+
+    puts(result);
+
+    amfree(result);
+    amfree(config_dir);
+    amfree(config_name);
+    for(i = 0; i < 3; i++) {
+       amfree(build_info[i].value);
+    }
+
+    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 0;
+}
diff --git a/server-src/holding.c b/server-src/holding.c
new file mode 100644 (file)
index 0000000..a734aa9
--- /dev/null
@@ -0,0 +1,612 @@
+/*
+ * 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: holding.c,v 1.17.2.12.4.3.2.10 2003/06/14 13:47:05 martinea Exp $
+ *
+ * Functions to access holding disk
+ */
+
+#include "amanda.h"
+#include "util.h"
+#include "holding.h"
+#include "fileheader.h"
+#include "util.h"
+#include "logfile.h"
+
+static sl_t *scan_holdingdisk P((sl_t *holding_list, char *diskdir, int verbose));
+
+int is_dir(fname)
+char *fname;
+{
+    struct stat statbuf;
+
+    if(stat(fname, &statbuf) == -1) return 0;
+
+    return (statbuf.st_mode & S_IFDIR) == S_IFDIR;
+}
+
+int is_emptyfile(fname)
+char *fname;
+{
+    struct stat statbuf;
+
+    if(stat(fname, &statbuf) == -1) return 0;
+
+    return (statbuf.st_mode & S_IFDIR) != S_IFDIR && statbuf.st_size == 0;
+}
+
+int is_datestr(fname)
+char *fname;
+/* sanity check on datestamp of the form YYYYMMDD */
+{
+    char *cp;
+    int ch, num, date, year, month;
+
+    /* must be 8 digits */
+    for(cp = fname; (ch = *cp) != '\0'; cp++) {
+       if(!isdigit(ch)) {
+           break;
+       }
+    }
+    if(ch != '\0' || cp-fname != 8) {
+       return 0;
+    }
+
+    /* sanity check year, month, and day */
+
+    num = atoi(fname);
+    year = num / 10000;
+    month = (num / 100) % 100;
+    date = num % 100;
+    if(year<1990 || year>2100 || month<1 || month>12 || date<1 || date>31)
+       return 0;
+
+    /* yes, we passed all the checks */
+
+    return 1;
+}
+
+
+int non_empty(fname)
+char *fname;
+{
+    DIR *dir;
+    struct dirent *entry;
+    int gotentry;
+
+    if((dir = opendir(fname)) == NULL)
+       return 0;
+
+    gotentry = 0;
+    while(!gotentry && (entry = readdir(dir)) != NULL) {
+       gotentry = !is_dot_or_dotdot(entry->d_name);
+    }
+
+    closedir(dir);
+    return gotentry;
+}
+
+
+sl_t *scan_holdingdisk(holding_list, diskdir, verbose)
+sl_t *holding_list;
+char *diskdir;
+int verbose;
+{
+    DIR *topdir;
+    struct dirent *workdir;
+    char *entryname = NULL;
+
+    if((topdir = opendir(diskdir)) == NULL) {
+       if(verbose && errno != ENOENT)
+          printf("Warning: could not open holding dir %s: %s\n",
+                 diskdir, strerror(errno));
+       return holding_list;
+    }
+
+    /* find all directories of the right format  */
+
+    if(verbose)
+       printf("Scanning %s...\n", diskdir);
+    while((workdir = readdir(topdir)) != NULL) {
+       if(is_dot_or_dotdot(workdir->d_name)
+          || strcmp(workdir->d_name, "lost+found") == 0) {
+           continue;
+       }
+       entryname = newvstralloc(entryname,
+                                diskdir, "/", workdir->d_name, NULL);
+       if(verbose) {
+           printf("  %s: ", workdir->d_name);
+       }
+       if(!is_dir(entryname)) {
+           if(verbose)
+               puts("skipping cruft file, perhaps you should delete it.");
+       } else if(!is_datestr(workdir->d_name)) {
+           if(verbose)
+               puts("skipping cruft directory, perhaps you should delete it.");
+       } else {
+           holding_list = insert_sort_sl(holding_list, workdir->d_name);
+           if(verbose)
+               puts("found Amanda directory.");
+       }
+    }
+    closedir(topdir);
+    amfree(entryname);
+    return holding_list;
+}
+
+
+sl_t *scan_holdingdir(holding_list, holdp, datestamp)
+sl_t *holding_list;
+holdingdisk_t *holdp;
+char *datestamp;
+{
+    DIR *workdir;
+    struct dirent *entry;
+    char *dirname = NULL;
+    char *destname = NULL;
+    disk_t *dp;
+    dumpfile_t file;
+
+    dirname = vstralloc(holdp->diskdir, "/", datestamp, NULL);
+    if((workdir = opendir(dirname)) == NULL) {
+       if(errno != ENOENT)
+           log_add(L_INFO, "%s: could not open dir: %s",
+                   dirname, strerror(errno));
+       amfree(dirname);
+       return holding_list;
+    }
+    chdir(dirname);
+    while((entry = readdir(workdir)) != NULL) {
+       if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
+           continue;
+
+       if(is_emptyfile(entry->d_name))
+           continue;
+
+       destname = newvstralloc(destname,
+                               dirname, "/", entry->d_name,
+                               NULL);
+       get_dumpfile(destname, &file);
+       if( file.type != F_DUMPFILE) {
+           if( file.type != F_CONT_DUMPFILE )
+               log_add(L_INFO, "%s: ignoring cruft file.", entry->d_name);
+           continue;
+       }
+
+       dp = lookup_disk(file.name, file.disk);
+
+       if (dp == NULL) {
+           log_add(L_INFO, "%s: disk %s:%s not in database, skipping it.",
+                   entry->d_name, file.name, file.disk);
+           continue;
+       }
+
+       if(file.dumplevel < 0 || file.dumplevel > 9) {
+           log_add(L_INFO, "%s: ignoring file with bogus dump level %d.",
+                   entry->d_name, file.dumplevel);
+           continue;
+       }
+
+       holding_list = append_sl(holding_list, destname);
+    }
+    closedir(workdir);
+    amfree(dirname);
+    amfree(destname);
+    return holding_list;
+}
+
+
+sl_t *get_flush(dateargs, datestamp, amflush, verbose)
+sl_t *dateargs;
+char *datestamp;  /* don't do this date */
+int amflush, 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);
+
+    holding_list = new_sl();
+
+    if(dateargs) {
+       int ok;
+
+       date_list = pick_all_datestamp(verbose);
+       for(date = date_list->first; date != NULL;) {
+           next_date = date->next;
+           ok = 0;
+           for(datearg=dateargs->first; datearg != NULL && ok==0;
+               datearg = datearg->next) {
+               ok = match_datestamp(datearg->name, date->name);
+           }
+           if(ok == 0) { /* remove dir */
+               remove_sl(date_list, date);
+           }
+           date = next_date;
+       }
+    }
+    else if (amflush) {
+       date_list = pick_datestamp(verbose);
+    }
+    else {
+       date_list = pick_all_datestamp(verbose);
+    }
+
+    for(date = date_list->first; date !=NULL; date = date->next) {
+       if(!datestamp || strcmp(datestamp,date->name) != 0) {
+           for(hdisk = getconf_holdingdisks(); hdisk != NULL;
+                                               hdisk = hdisk->next) {
+               holding_list = scan_holdingdir(holding_list, hdisk, date->name);
+           }
+       }
+    }
+
+    free_sl(date_list);
+    date_list = NULL;
+    chdir(current_dir);
+    return(holding_list);
+}
+
+
+sl_t *pick_all_datestamp(verbose)
+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);
+
+    return holding_list;
+}
+
+
+sl_t *pick_datestamp(verbose)
+int verbose;
+{
+    sl_t *holding_list;
+    sl_t *r_holding_list = NULL;
+    sle_t *dir;
+    char **directories = NULL;
+    int i;
+    char *answer = NULL;
+    char *a;
+    int ch;
+    char max_char = '\0', chupper = '\0';
+
+    holding_list = pick_all_datestamp(verbose);
+
+    if(holding_list->nb_element == 0) {
+       return holding_list;
+    }
+    else if(holding_list->nb_element == 1 || !verbose) {
+       return holding_list;
+    }
+    else {
+       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;
+       }
+
+       while(1) {
+           puts("\nMultiple Amanda directories, please pick one by letter:");
+           for(dir = holding_list->first, max_char = 'A';
+               dir != NULL && max_char <= 'Z';
+               dir = dir->next, max_char++) {
+               printf("  %c. %s\n", max_char, dir->name);
+           }
+           max_char--;
+           printf("Select directories to flush [A..%c]: [ALL] ", max_char);
+           fflush(stdout); fflush(stderr);
+           amfree(answer);
+           if ((answer = agets(stdin)) == NULL) {
+               clearerr(stdin);
+               continue;
+           }
+           a = answer;
+           while ((ch = *a++) != '\0' && isspace(ch)) {}
+           if(ch == '\0' || strncasecmp(a, "ALL", 3) == 0) {
+               break;
+           }
+           do {
+               if (isspace(ch) || ch == ',') {
+                   continue;
+               }
+               chupper = toupper(ch);
+               if (chupper < 'A' || chupper > max_char) {
+                   free_sl(r_holding_list);
+                   r_holding_list = NULL;
+                   break;
+               }
+               r_holding_list = append_sl(r_holding_list,
+                                          directories[chupper - 'A']);
+           } while ((ch = *a++) != '\0');
+           if (r_holding_list && ch == '\0') {
+               free_sl(holding_list);
+               holding_list = r_holding_list;
+               break;
+           }
+       }
+    }
+    amfree(directories);
+    amfree(answer);
+    return holding_list;
+}
+
+
+filetype_t get_amanda_names(fname, hostname, diskname, level)
+char *fname, **hostname, **diskname;
+int *level;
+{
+    dumpfile_t file;
+    char buffer[DISK_BLOCK_BYTES];
+    int fd;
+    *hostname = *diskname = NULL;
+
+    if((fd = open(fname, O_RDONLY)) == -1)
+       return F_UNKNOWN;
+
+    if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+       aclose(fd);
+       return F_UNKNOWN;
+    }
+    aclose(fd);
+
+    parse_file_header(buffer,&file,sizeof(buffer));
+    if(file.type != F_DUMPFILE && file.type != F_CONT_DUMPFILE) {
+       return file.type;
+    }
+    *hostname = stralloc(file.name);
+    *diskname = stralloc(file.disk);
+    *level = file.dumplevel;
+
+    return file.type;
+}
+
+
+void get_dumpfile(fname, file)
+char *fname;
+dumpfile_t *file;
+{
+    char buffer[DISK_BLOCK_BYTES];
+    int fd;
+
+    fh_init(file);
+    file->type = F_UNKNOWN;
+    if((fd = open(fname, O_RDONLY)) == -1)
+       return;
+
+    if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+       aclose(fd);
+       return;
+    }
+    aclose(fd);
+
+    parse_file_header(buffer,file,sizeof(buffer));
+    return;
+}
+
+
+long size_holding_files(holding_file)
+char *holding_file;
+{
+    int fd;
+    int buflen;
+    char buffer[DISK_BLOCK_BYTES];
+    dumpfile_t file;
+    char *filename;
+    long size=0;
+    struct stat finfo;
+
+    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;
+       }
+       buflen = fullread(fd, buffer, sizeof(buffer));
+       parse_file_header(buffer, &file, buflen);
+       close(fd);
+       if(stat(filename, &finfo) == -1) {
+           printf("stat %s: %s\n", filename, strerror(errno));
+           finfo.st_size = 0;
+       }
+       size += (finfo.st_size+1023)/1024;
+       filename = newstralloc(filename, file.cont_filename);
+    }
+    amfree(filename);
+    return size;
+}
+
+
+int unlink_holding_files( holding_file )
+char *holding_file;
+{
+    int fd;
+    int buflen;
+    char buffer[DISK_BLOCK_BYTES];
+    dumpfile_t file;
+    char *filename;
+
+    filename = stralloc(holding_file);
+    while(filename != NULL && filename[0] != '\0') {
+       if((fd = open(filename,O_RDONLY)) == -1) {
+           fprintf(stderr,"unlink_holding_files: open of %s failed: %s\n",filename,strerror(errno));
+           amfree(filename);
+           return 0;
+       }
+       buflen = fullread(fd, buffer, sizeof(buffer));
+       parse_file_header(buffer, &file, buflen);
+       close(fd);
+       unlink(filename);
+       filename = newstralloc(filename,file.cont_filename);
+    }
+    amfree(filename);
+    return 1;
+}
+
+
+int rename_tmp_holding( holding_file, complete )
+char *holding_file;
+int complete;
+{
+    int fd;
+    int buflen;
+    char buffer[DISK_BLOCK_BYTES];
+    dumpfile_t file;
+    char *filename;
+    char *filename_tmp = NULL;
+
+    filename = stralloc(holding_file);
+    while(filename != NULL && filename[0] != '\0') {
+       filename_tmp = newvstralloc(filename_tmp, filename, ".tmp", NULL);
+       if((fd = open(filename_tmp,O_RDONLY)) == -1) {
+           fprintf(stderr,"rename_tmp_holding: open of %s failed: %s\n",filename_tmp,strerror(errno));
+           amfree(filename);
+           amfree(filename_tmp);
+           return 0;
+       }
+       buflen = fullread(fd, buffer, sizeof(buffer));
+       if (buflen == 0) {
+           fprintf(stderr,"rename_tmp_holding: %s: empty file?\n", filename_tmp);
+           amfree(filename);
+           amfree(filename_tmp);
+           close(fd);
+           return 0;
+       }
+       parse_file_header(buffer, &file, buflen);
+       close(fd);
+       if(complete == 0 ) {
+           if((fd = open(filename_tmp,O_RDWR)) == -1) {
+               fprintf(stderr, "rename_tmp_holdingX: open of %s failed: %s\n",
+                       filename_tmp, strerror(errno));
+               amfree(filename);
+               amfree(filename_tmp);
+               return 0;
+
+           }
+           file.is_partial = 1;
+           build_header(buffer, &file, sizeof(buffer));
+           fullwrite(fd, buffer, sizeof(buffer));
+           close(fd);
+       }
+       if(rename(filename_tmp, filename) != 0) {
+           fprintf(stderr,
+                   "rename_tmp_holding(): could not rename \"%s\" to \"%s\": %s",
+                   filename_tmp, filename, strerror(errno));
+       }
+       filename = newstralloc(filename, file.cont_filename);
+    }
+    amfree(filename);
+    amfree(filename_tmp);
+    return 1;
+}
+
+
+void cleanup_holdingdisk(diskdir, verbose)
+char *diskdir;
+int verbose;
+{
+    DIR *topdir;
+    struct dirent *workdir;
+
+    if((topdir = opendir(diskdir)) == NULL) {
+       if(verbose && errno != ENOENT)
+           printf("Warning: could not open holding dir %s: %s\n",
+                  diskdir, strerror(errno));
+       return;
+   }
+
+    /* find all directories of the right format  */
+
+    if(verbose)
+       printf("Scanning %s...\n", diskdir);
+    chdir(diskdir);
+    while((workdir = readdir(topdir)) != NULL) {
+       if(is_dot_or_dotdot(workdir->d_name)
+          || strcmp(workdir->d_name, "lost+found") == 0) {
+           continue;
+       }
+       if(verbose)
+           printf("  %s: ", workdir->d_name);
+       if(!is_dir(workdir->d_name)) {
+           if(verbose)
+               puts("skipping cruft file, perhaps you should delete it.");
+       }
+       else if(!is_datestr(workdir->d_name)) {
+           if(verbose)
+               puts("skipping cruft directory, perhaps you should delete it.");
+       }
+       else if(rmdir(workdir->d_name) == 0) {
+           if(verbose)
+               puts("deleted empty Amanda directory.");
+       }
+     }
+     closedir(topdir);
+}
+
+
+int mkholdingdir(diskdir)
+char *diskdir;
+{
+    struct stat stat_hdp;
+    int success = 1;
+
+    if (mkpdir(diskdir, 0770, (uid_t)-1, (gid_t)-1) != 0 && errno != EEXIST) {
+       log_add(L_WARNING, "WARNING: could not create parents of %s: %s",
+               diskdir, strerror(errno));
+       success = 0;
+    }
+    else if (mkdir(diskdir, 0770) != 0 && errno != EEXIST) {
+       log_add(L_WARNING, "WARNING: could not create %s: %s",
+               diskdir, strerror(errno));
+       success = 0;
+    }
+    else if (stat(diskdir, &stat_hdp) == -1) {
+       log_add(L_WARNING, "WARNING: could not stat %s: %s",
+               diskdir, strerror(errno));
+       success = 0;
+    }
+    else {
+       if (!S_ISDIR((stat_hdp.st_mode))) {
+           log_add(L_WARNING, "WARNING: %s is not a directory",
+                   diskdir);
+           success = 0;
+       }
+       else if (access(diskdir,W_OK) != 0) {
+           log_add(L_WARNING, "WARNING: directory %s is not writable",
+                   diskdir);
+           success = 0;
+       }
+    }
+    return success;
+}
diff --git a/server-src/holding.h b/server-src/holding.h
new file mode 100644 (file)
index 0000000..e2aead2
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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: holding.h,v 1.11.2.7.4.1.2.2 2003/06/03 20:14:44 martinea Exp $
+ *
+ */
+
+#ifndef HOLDING_H
+#define HOLDING_H
+
+#include "amanda.h"
+#include "diskfile.h"
+#include "fileheader.h"
+#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));
+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,
+                              char **hostname,
+                              char **diskname,
+                              int *level));
+void get_dumpfile P((char *fname, dumpfile_t *file));
+long size_holding_files P((char *holding_file));
+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));
+
+
+#endif /* HOLDING_H */
diff --git a/server-src/infofile.c b/server-src/infofile.c
new file mode 100644 (file)
index 0000000..ae41ff6
--- /dev/null
@@ -0,0 +1,817 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: infofile.c,v 1.44.4.4 1999/11/10 14:36:10 oliva Exp $
+ *
+ * manage current info file
+ */
+#include "amanda.h"
+#include "conffile.h"
+#include "infofile.h"
+#include "token.h"
+
+#ifdef TEXTDB
+  static char *infodir = (char *)0;
+  static char *infofile = (char *)0;
+  static char *newinfofile;
+  static int writing;
+#else
+#  define MAX_KEY 256
+/*#  define HEADER     (sizeof(info_t)-DUMP_LEVELS*sizeof(stats_t))*/
+
+  static DBM *infodb = NULL;
+  static lockfd = -1;
+#endif
+
+#ifdef TEXTDB
+
+FILE *open_txinfofile(host, disk, mode)
+char *host;
+char *disk;
+char *mode;
+{
+    FILE *infof;
+
+    assert(infofile == (char *)0);
+
+    writing = (*mode == 'w');
+
+    host = sanitise_filename(host);
+    disk = sanitise_filename(disk);
+
+    infofile = vstralloc(infodir,
+                        "/", host,
+                        "/", disk,
+                        "/info",
+                        NULL);
+
+    amfree(host);
+    amfree(disk);
+
+    /* create the directory structure if in write mode */
+    if (writing) {
+        if (mkpdir(infofile, 02755, (uid_t)-1, (gid_t)-1) == -1) {
+           amfree(infofile);
+           return NULL;
+       }
+    }
+
+    newinfofile = stralloc2(infofile, ".new");
+
+    if(writing) {
+       infof = fopen(newinfofile, mode);
+       if(infof != NULL)
+           amflock(fileno(infof), "info");
+    }
+    else {
+       infof = fopen(infofile, mode);
+       /* no need to lock readers */
+    }
+
+    if(infof == (FILE *)0) {
+       amfree(infofile);
+       amfree(newinfofile);
+       return NULL;
+    }
+
+    return infof;
+}
+
+int close_txinfofile(infof)
+FILE *infof;
+{
+    int rc = 0;
+
+    assert(infofile != (char *)0);
+
+    if(writing) {
+       rc = rename(newinfofile, infofile);
+
+       amfunlock(fileno(infof), "info");
+    }
+
+    amfree(infofile);
+    amfree(newinfofile);
+
+    rc = rc || fclose(infof);
+    infof = NULL;
+    if (rc) rc = -1;
+
+    return rc;
+}
+
+int read_txinfofile(infof, info) /* XXX - code assumes AVG_COUNT == 3 */
+FILE *infof;
+info_t *info;
+{
+    char *line = NULL;
+    int version;
+    int rc;
+    perf_t *pp;
+    char *s;
+    int ch;
+
+    /* get version: command: lines */
+
+    if((line = agets(infof)) == 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);
+    amfree(line);
+    if(rc != 1) return -2;
+
+    /* get rate: and comp: lines for full dumps */
+
+    pp = &info->full;
+
+    if((line = agets(infof)) == NULL) return -1;
+    rc = sscanf(line, "full-rate: %f %f %f",
+               &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",
+               &pp->comp[0], &pp->comp[1], &pp->comp[2]);
+    amfree(line);
+    if(rc > 3) return -2;
+
+    /* get rate: and comp: lines for incr dumps */
+
+    pp = &info->incr;
+
+    if((line = agets(infof)) == NULL) return -1;
+    rc = sscanf(line, "incr-rate: %f %f %f",
+               &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",
+               &pp->comp[0], &pp->comp[1], &pp->comp[2]);
+    amfree(line);
+    if(rc > 3) return -2;
+
+    /* get stats for dump levels */
+
+    for(rc = -2; (line = agets(infof)) != NULL; free(line)) {
+       stats_t onestat;        /* one stat record */
+       long date;
+       int level;
+
+       if(line[0] == '/' && line[1] == '/') {
+           rc = 0;
+           amfree(line);
+           return 0;                           /* normal end of record */
+       }
+       else if (strncmp(line,"last_level:",11) == 0) {
+           break;                              /* normal */
+       }
+       memset(&onestat, 0, sizeof(onestat));
+
+       s = line;
+       ch = *s++;
+
+#define sc "stats:"
+       if(strncmp(line, sc, sizeof(sc)-1) != 0) {
+           break;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf((s - 1), "%d", &level) != 1) {
+           break;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.size) != 1) {
+           break;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.csize) != 1) {
+           break;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf((s - 1), "%ld", &onestat.secs) != 1) {
+           break;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf((s - 1), "%ld", &date) != 1) {
+           break;
+       }
+       skip_integer(s, ch);
+
+       skip_whitespace(s, ch);
+       if(ch != '\0') {
+           if(sscanf((s - 1), "%d", &onestat.filenum) != 1) {
+               break;
+           }
+           skip_integer(s, ch);
+
+           skip_whitespace(s, ch);
+           if(ch == '\0') {
+               break;
+           }
+           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 */
+
+       if(level < 0 || level > DUMP_LEVELS-1) break;
+
+       info->inf[level] = onestat;
+    }
+   
+    if(line == NULL) return -1;
+
+    rc = sscanf(line, "last_level: %d %d", 
+               &info->last_level, &info->consecutive_runs);
+               
+    amfree(line);
+    if(rc > 2) return -2;
+    rc = 0;
+
+    if((line = agets(infof)) == NULL) return -1;
+    amfree(line);
+
+    return rc;
+}
+
+int write_txinfofile(infof, info)
+FILE *infof;
+info_t *info;
+{
+    int i;
+    stats_t *sp;
+    perf_t *pp;
+    int level;
+
+    fprintf(infof, "version: %d\n", 0);
+
+    fprintf(infof, "command: %d\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, "\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, "\n");
+
+    pp = &info->incr;
+
+    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, "\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, "\n");
+
+    for(level=0; level<DUMP_LEVELS; level++) {
+       sp = &info->inf[level];
+
+       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);
+       if(sp->label[0] != '\0')
+           fprintf(infof, " %d %s", sp->filenum, sp->label);
+       fprintf(infof, "\n");
+    }
+
+    fprintf(infof, "last_level: %d %d\n", info->last_level, info->consecutive_runs);
+    fprintf(infof, "//\n");
+
+    return 0;
+}
+
+int delete_txinfofile(host, disk)
+char *host;
+char *disk;
+{
+    char *fn = NULL, *fn_new = NULL;
+    int rc;
+
+    host = sanitise_filename(host);
+    disk = sanitise_filename(disk);
+    fn = vstralloc(infodir,
+                  "/", host,
+                  "/", disk,
+                  "/info",
+                  NULL);
+    fn_new = stralloc2(fn, ".new");
+
+    amfree(host);
+    amfree(disk);
+
+    unlink(fn_new);
+    amfree(fn_new);
+
+    rc = rmpdir(fn, infodir);
+    amfree(fn);
+
+    return rc;
+}
+#endif
+
+#ifndef TEXTDB
+static char *lockname = NULL;
+#endif
+
+int open_infofile(filename)
+char *filename;
+{
+#ifdef TEXTDB
+    assert(infodir == (char *)0);
+
+    infodir = stralloc(filename);
+
+    return 0; /* success! */
+#else
+    /* lock the dbm file */
+
+    lockname = newstralloc2(lockname, filename, ".lck");
+    if((lockfd = open(lockname, O_CREAT|O_RDWR, 0644)) == -1)
+       return 2;
+
+    if(amflock(lockfd, "info") == -1) {
+       aclose(lockfd);
+       unlink(lockname);
+       return 3;
+    }
+
+    if(!(infodb = dbm_open(filename, O_CREAT|O_RDWR, 0644))) {
+       amfunlock(lockfd, "info");
+       aclose(lockfd);
+       unlink(lockname);
+       return 1;
+    }
+
+    return (infodb == NULL);   /* return 1 on error */
+#endif
+}
+
+void close_infofile()
+{
+#ifdef TEXTDB
+    assert(infodir != (char *)0);
+
+    amfree(infodir);
+#else
+    dbm_close(infodb);
+
+    if(amfunlock(lockfd, "info") == -1)
+       error("could not unlock infofile: %s", strerror(errno));
+
+    aclose(lockfd);
+    lockfd = -1;
+
+    unlink(lockname);
+#endif
+}
+
+/* Convert a dump level to a GMT based time stamp */
+char *get_dumpdate(info, lev)
+info_t *info;
+int lev;
+{
+    static char stamp[20]; /* YYYY:MM:DD:hh:mm:ss */
+    int l;
+    time_t this, last;
+    struct tm *t;
+
+    last = EPOCH;
+
+    for(l = 0; l < lev; l++) {
+       this = info->inf[l].date;
+       if (this > last) last = this;
+    }
+
+    t = gmtime(&last);
+    ap_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 */
+{
+    double sum;        /* running total */
+    int n;     /* number of items in sum */
+    int w;     /* weight */
+    int i;     /* counter */
+
+    sum = 0.0;
+    n = 0;
+
+    for(i = 0; i < AVG_COUNT; i++) {
+       if(a[i] >= 0.0) {
+           w = AVG_COUNT - i;
+           sum += a[i] * w;
+           n += w;
+       }
+    }
+
+    if(n == 0) return d;
+    return sum / n;
+}
+
+void zero_info(info)
+info_t *info;
+{
+    int i;
+
+    memset(info, '\0', sizeof(info_t));
+
+    for(i = 0; i < AVG_COUNT; i++) {
+       info->full.comp[i] = info->incr.comp[i] = -1.0;
+       info->full.rate[i] = info->incr.rate[i] = -1.0;
+    }
+
+    for(i = 0; i < DUMP_LEVELS; i++) {
+       info->inf[i].date = (time_t)-1;
+    }
+
+    info->last_level = -1;
+    info->consecutive_runs = -1;
+
+    return;
+}
+
+int get_info(hostname, diskname, info)
+char *hostname, *diskname;
+info_t *info;
+{
+    int rc;
+
+    (void) zero_info(info);
+
+    {
+#ifdef TEXTDB
+       FILE *infof;
+
+       infof = open_txinfofile(hostname, diskname, "r");
+
+       if(infof == NULL) {
+           rc = -1; /* record not found */
+       }
+       else {
+           rc = read_txinfofile(infof, info);
+
+           close_txinfofile(infof);
+       }
+#else
+       datum k, d;
+
+       /* setup key */
+
+       k.dptr = vstralloc(hostname, ":", diskname, NULL);
+       k.dsize = strlen(k.dptr)+1;
+
+       /* lookup record */
+
+       d = dbm_fetch(infodb, k);
+       amfree(k.dptr);
+       if(d.dptr == NULL) {
+           rc = -1; /* record not found */
+       }
+       else {
+           memcpy(info, d.dptr, d.dsize);
+           rc = 0;
+       }
+#endif
+    }
+
+    return rc;
+}
+
+
+int get_firstkey(hostname, hostname_size, diskname, diskname_size)
+char *hostname, *diskname;
+int hostname_size, diskname_size;
+{
+#ifdef TEXTDB
+    assert(0);
+    return 0;
+#else
+    datum k;
+    int rc;
+    char *s, *fp;
+    int ch;
+
+    k = dbm_firstkey(infodb);
+    if(k.dptr == NULL) return 0;
+
+    s = k.dptr;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') return 0;
+    fp = hostname;
+    while(ch && ch != ':') {
+       if(fp >= hostname+hostname_size-1) {
+           fp = NULL;
+           break;
+       }
+       *fp = ch;
+       ch = *s++;
+    }
+    if(fp == NULL) return 0;
+    *fp = '\0';
+
+    if(ch != ':') return 0;
+    ch = *s++;
+    copy_string(s, ch, diskname, diskname_size, fp);
+    if(fp == NULL) return 0;
+
+    return 1;
+#endif
+}
+
+
+int get_nextkey(hostname, hostname_size, diskname, diskname_size)
+char *hostname, *diskname;
+int hostname_size, diskname_size;
+{
+#ifdef TEXTDB
+    assert(0);
+    return 0;
+#else
+    datum k;
+    int rc;
+    char *s, *fp;
+    int ch;
+
+    k = dbm_nextkey(infodb);
+    if(k.dptr == NULL) return 0;
+
+    s = k.dptr;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') return 0;
+    fp = hostname;
+    while(ch && ch != ':') {
+       if(fp >= hostname+hostname_size-1) {
+           fp = NULL;
+           break;
+       }
+       *fp = ch;
+       ch = *s++;
+    }
+    if(fp == NULL) return 0;
+    *fp = '\0';
+
+    if(ch != ':') return 0;
+    ch = *s++;
+    copy_string(s, ch, diskname, diskname_size, fp);
+    if(fp == NULL) return 0;
+
+    return 1;
+#endif
+}
+
+
+int put_info(hostname, diskname, info)
+     char *hostname, *diskname;
+     info_t *info;
+{
+#ifdef TEXTDB
+    FILE *infof;
+    int rc;
+
+    infof = open_txinfofile(hostname, diskname, "w");
+
+    if(infof == NULL) return -1;
+
+    rc = write_txinfofile(infof, info);
+
+    rc = rc || close_txinfofile(infof);
+
+    return rc;
+#else
+    datum k, d;
+    int maxlev;
+
+    /* setup key */
+
+    k.dptr = vstralloc(hostname, ":", diskname, NULL);
+    k.dsize = strlen(k.dptr)+1;
+
+    d.dptr = (char *)info;
+    d.dsize = sizeof(info_t);
+
+    /* store record */
+
+    if(dbm_store(infodb, k, d, DBM_REPLACE) != 0) {
+       amfree(k.dptr);
+       return -1;
+    }
+
+    amfree(k.dptr);
+    return 0;
+#endif
+}
+
+
+int del_info(hostname, diskname)
+char *hostname, *diskname;
+{
+#ifdef TEXTDB
+    return delete_txinfofile(hostname, diskname);
+#else
+    char key[MAX_KEY];
+    datum k;
+
+    /* setup key */
+
+    k.dptr = vstralloc(hostname, ":", diskname, NULL);
+    k.dsize = strlen(key)+1;
+
+    /* delete key and record */
+
+    if(dbm_delete(infodb, k) != 0) {
+       amfree(k.dptr);
+       return -1;
+    }
+    amfree(k.dptr);
+    return 0;
+#endif
+}
+
+
+#ifdef TEST
+
+void dump_rec(info)
+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",
+          info->full.rate[0],info->full.rate[1],info->full.rate[2]);
+    printf("full comp rate %5.1f, %5.1f, %5.1f\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",
+          info->incr.rate[0],info->incr.rate[1],info->incr.rate[2]);
+    printf("incr comp rate %5.1f, %5.1f, %5.1f\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",
+                  i, (long)sp->date, sp->label, sp->filenum,
+                  sp->size, sp->csize, sp->secs);
+       }
+    }
+    putchar('\n');
+   printf("last_level: %d %d\n", info->last_level, info->consecutive_runs);
+}
+
+#ifdef TEXTDB
+void dump_db(host, disk)
+char *host, *disk;
+{
+    info_t info;
+    int rc;
+
+    if((rc = get_info(host, disk, &info)) == 0) {
+       dump_rec(&info);
+    } else {
+       printf("cannot fetch information for %s:%s rc=%d\n", host, disk, rc);
+    }
+}
+#else
+void dump_db(str)
+char *str;
+{
+    datum k,d;
+    int rec,r,num;
+    info_t info;
+
+
+    printf("info database %s:\n--------\n", str);
+    rec = 0;
+    k = dbm_firstkey(infodb);
+    while(k.dptr != NULL) {
+
+       printf("%3d: KEY %s =\n", rec, k.dptr);
+
+       d = dbm_fetch(infodb, k);
+       memset(&info, '\0', sizeof(info));
+       memcpy(&info, d.dptr, d.dsize);
+
+       num = (d.dsize-HEADER)/sizeof(stats_t);
+       dump_rec(&info);
+
+       k = dbm_nextkey(infodb);
+       rec++;
+    }
+    puts("--------\n");
+}
+#endif
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+  int i;
+  int fd;
+  unsigned long malloc_hist_1, malloc_size_1;
+  unsigned long malloc_hist_2, malloc_size_2;
+
+  for(fd = 3; fd < 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
+     * descriptor, which in turn might be used as an index into
+     * an array (e.g. an fd_set).
+     */
+    close(fd);
+  }
+
+  set_pname("infofile");
+
+  malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+  for(i = 1; i < argc; ++i) {
+#ifdef TEXTDB
+    if(i+1 >= argc) {
+      fprintf(stderr,"usage: %s host disk [host disk ...]\n",argv[0]);
+      return 1;
+    }
+    open_infofile("curinfo");
+    dump_db(argv[i], argv[i+1]);
+    i++;
+#else
+    open_infofile(argv[i]);
+    dump_db(argv[i]);
+#endif
+    close_infofile();
+  }
+
+  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 0;
+}
+
+#endif /* TEST */
diff --git a/server-src/infofile.h b/server-src/infofile.h
new file mode 100644 (file)
index 0000000..813d816
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: infofile.h,v 1.7.4.4 1998/12/03 03:02:45 martinea Exp $
+ *
+ * interface for current info file reading code
+ */
+#ifndef INFOFILE_H
+#define INFOFILE_H
+
+#include "amanda.h"
+
+#define DUMP_LEVELS    10
+#define MAX_LABEL      80
+#define EPOCH          ((time_t)0)
+
+#define AVG_COUNT      3
+#define newperf(ary,f) ( ary[2]=ary[1], ary[1]=ary[0], ary[0]=(f) )
+
+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 */
+    time_t date;               /* end time of dump */
+    /* fields updated by taper */
+    int filenum;               /* file number on tape */
+    char label[MAX_LABEL];     /* tape label */
+} stats_t;
+
+typedef struct perf_s {
+    float rate[AVG_COUNT];
+    float comp[AVG_COUNT];
+} perf_t;
+
+typedef struct info_s {
+    unsigned int  command;             /* command word */
+#      define NO_COMMAND       0       /* no outstanding commands */
+#      define FORCE_FULL       1       /* force level 0 at next run */
+#      define FORCE_BUMP       2       /* force bump at next run */
+#      define FORCE_NO_BUMP    4       /* force no-bump at next run */
+    perf_t  full;
+    perf_t  incr;
+    stats_t inf[DUMP_LEVELS];
+    int last_level, consecutive_runs;
+} info_t;
+
+
+int open_infofile P((char *infofile));
+void close_infofile P((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));
+
+#endif /* ! INFOFILE_H */
diff --git a/server-src/list_dir.c b/server-src/list_dir.c
new file mode 100644 (file)
index 0000000..14c9084
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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: list_dir.c,v 1.14.4.2.6.1 2002/03/24 19:23:24 jrjackson Exp $
+ *
+ * manage directory listings from index files
+ */
+
+#include "amanda.h"
+#include "disk_history.h"
+#include "list_dir.h"
+
+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()
+{
+    return dir_list;
+}
+
+
+void clear_dir_list P((void))
+{
+    DIR_ITEM *this;
+
+    if (dir_list == NULL)
+       return;
+
+    do
+    {
+       this = dir_list;
+       dir_list = dir_list->next;
+       amfree(this->path);
+       amfree(this);
+    } while (dir_list != NULL);
+
+    dir_last = NULL;
+    cur_list = NULL;
+}
+
+/* add item to list if path not already on list                     */
+/* Since this function is almost called with increasing path order, */
+/* we keep a pointer on the last element added (cur_list), this     */
+/* reduce the time for the search of a path.                        */
+/* 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;
+{
+    DIR_ITEM *cur;
+
+    if (dir_list == NULL)
+    {
+       dir_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       dir_list->next = NULL;
+       dir_list->dump = dump;
+       dir_list->path = stralloc(path);
+       dir_last=dir_list;
+       cur_list=dir_list;
+       return 0; /* added */
+    }
+
+    if(strcmp(path,dir_last->path) == 0)
+       return 0; /* found */
+
+    /* add at head of list */
+    if(strcmp(path,dir_list->path) < 0)
+    {
+       cur_list = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       cur_list->next = dir_list;
+       cur_list->dump = dump;
+       cur_list->path = stralloc(path);
+       dir_list = cur_list;
+       return 0; /* added */
+    }
+
+    /* if smaller than last path */
+    if(strcmp(path,dir_last->path) < 0)
+    {
+       if(cur_list==NULL)
+           cur_list=dir_list;
+
+       /* reset cur_list if path is smaller than cur_list->path */
+       if(strcmp(path,cur_list->path) < 0)
+           cur_list=dir_list;
+
+       if(strcmp(path,cur_list->path) == 0)
+           return 0; /* found */
+
+       while (cur_list->next!=NULL && (strcmp(path,cur_list->next->path) > 0))
+       {
+           cur_list=cur_list->next;
+       }
+
+       if(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->next = cur_list->next;
+       cur->dump = dump;
+       cur->path = stralloc(path);
+       cur_list->next=cur;
+       cur_list=cur;
+       return 0; /* added */
+    }
+    else /* add at end of list */
+    {
+       dir_last->next = (DIR_ITEM *)alloc(sizeof(DIR_ITEM));
+       dir_last=dir_last->next;
+       dir_last->next = NULL;
+       dir_last->dump = dump;
+       dir_last->path = stralloc(path);
+       return 0; /* added */
+    }
+}
diff --git a/server-src/list_dir.h b/server-src/list_dir.h
new file mode 100644 (file)
index 0000000..312fa60
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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: list_dir.h,v 1.2.4.1 1999/02/15 02:31:07 martinea Exp $
+ *
+ */
+
+typedef struct DIR_ITEM {
+    DUMP_ITEM *dump;
+    char *path;
+    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));
diff --git a/server-src/logfile.c b/server-src/logfile.c
new file mode 100644 (file)
index 0000000..9faf46f
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: logfile.c,v 1.17.4.1.4.2.2.3 2003/01/01 23:28:56 martinea Exp $
+ *
+ * common log file writing routine
+ */
+#include "amanda.h"
+#include "arglist.h"
+#include "conffile.h"
+
+#include "logfile.h"
+
+char *logtype_str[] = {
+    "BOGUS",
+    "FATAL",           /* program died for some reason, used by error() */
+    "ERROR", "WARNING",        "INFO", "SUMMARY",       /* information messages */
+    "START", "FINISH",                            /* start/end of a run */
+    "DISK",                                                     /* disk */
+    "SUCCESS", "FAIL", "STRANGE",                  /* the end of a dump */
+    "STATS",                                              /* statistics */
+    "MARKER",                                    /* marker for reporter */
+    "CONT"                                /* continuation line; special */
+};
+
+char *program_str[] = {
+    "UNKNOWN", "planner", "driver", "amreport", "dumper", "taper", "amflush"
+};
+
+int curlinenum;
+logtype_t curlog;
+program_t curprog;
+char *curstr;
+
+int multiline = -1;
+static char *logfile;
+static int logfd = -1;
+
+ /*
+  * Note that technically we could use two locks, a read lock
+  * from 0-EOF and a write-lock from EOF-EOF, thus leaving the
+  * beginning of the file open for read-only access.  Doing so
+  * would open us up to some race conditions unless we're pretty
+  * careful, and on top of that the functions here are so far
+  * the only accesses to the logfile, so keep things simple.
+  */
+
+/* local functions */
+static void open_log P((void));
+static void close_log P((void));
+
+void logerror(msg)
+char *msg;
+{
+    log_add(L_FATAL, "%s", msg);
+}
+
+printf_arglist_function1(void log_add, logtype_t, typ, char *, format)
+{
+    va_list argp;
+    int saved_errout;
+    char *leader = NULL;
+    char linebuf[STR_SIZE];
+    int l, n, s;
+
+
+    /* format error message */
+
+    if((int)typ <= (int)L_BOGUS || (int)typ > (int)L_MARKER) typ = L_BOGUS;
+
+    if(multiline > 0) {
+       leader = stralloc("  ");                /* continuation line */
+    } else {
+       leader = vstralloc(logtype_str[(int)typ], " ", get_pname(), " ", NULL);
+    }
+
+    arglist_start(argp, format);
+    ap_vsnprintf(linebuf, sizeof(linebuf)-1, format, argp);
+                                               /* -1 to allow for '\n' */
+    arglist_end(argp);
+
+    /* avoid recursive call from error() */
+
+    saved_errout = erroutput_type;
+    erroutput_type &= ~ERR_AMANDALOG;
+
+    /* append message to the log file */
+
+    if(multiline == -1) open_log();
+
+    for(l = 0, n = strlen(leader); l < n; l += s) {
+       if((s = write(logfd, leader + l, n - l)) < 0) {
+           error("log file write error: %s", strerror(errno));
+       }
+    }
+
+    amfree(leader);
+
+    n = strlen(linebuf);
+    if(n == 0 || linebuf[n-1] != '\n') linebuf[n++] = '\n';
+    linebuf[n] = '\0';
+
+    for(l = 0; l < n; l += s) {
+       if((s = write(logfd, linebuf + l, n - l)) < 0) {
+           error("log file write error: %s", strerror(errno));
+       }
+    }
+
+    if(multiline != -1) multiline++;
+    else close_log();
+
+    erroutput_type = saved_errout;
+}
+
+void log_start_multiline()
+{
+    assert(multiline == -1);
+
+    multiline = 0;
+    open_log();
+}
+
+
+void log_end_multiline()
+{
+    assert(multiline != -1);
+    multiline = -1;
+    close_log();
+}
+
+
+void log_rename(datestamp)
+char *datestamp;
+{
+    char *conf_logdir;
+    char *logfile;
+    char *fname = NULL;
+    char seq_str[NUM_STR_SIZE];
+    unsigned int seq;
+    struct stat statbuf;
+
+    if(datestamp == NULL) datestamp = "error";
+
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+       conf_logdir = stralloc(conf_logdir);
+    } else {
+       conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    logfile = vstralloc(conf_logdir, "/log", NULL);
+
+    for(seq = 0; 1; seq++) {   /* if you've got MAXINT files in your dir... */
+       ap_snprintf(seq_str, sizeof(seq_str), "%d", seq);
+       fname = newvstralloc(fname,
+                            logfile,
+                            ".", datestamp,
+                            ".", seq_str,
+                            NULL);
+       if(stat(fname, &statbuf) == -1 && errno == ENOENT) break;
+    }
+
+    if(rename(logfile, fname) != 0) {
+       error("could not rename \"%s\" to \"%s\": %s",
+             logfile, fname, strerror(errno));
+    }
+
+    amfree(fname);
+    amfree(logfile);
+    amfree(conf_logdir);
+}
+
+
+static void open_log()
+{
+    char *conf_logdir;
+
+    conf_logdir = getconf_str(CNF_LOGDIR);
+    if (*conf_logdir == '/') {
+       conf_logdir = stralloc(conf_logdir);
+    } else {
+       conf_logdir = stralloc2(config_dir, conf_logdir);
+    }
+    logfile = vstralloc(conf_logdir, "/log", NULL);
+    amfree(conf_logdir);
+
+    logfd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600);
+
+    if(logfd == -1) {
+       error("could not open log file %s: %s", logfile, strerror(errno));
+    }
+
+    if(amflock(logfd, "log") == -1)
+       error("could not lock log file %s: %s", logfile, strerror(errno));
+}
+
+
+static void close_log()
+{
+    if(amfunlock(logfd, "log") == -1)
+       error("could not unlock log file %s: %s", logfile, strerror(errno));
+
+    if(close(logfd) == -1)
+       error("close log file: %s", strerror(errno));
+
+    logfd = -1;
+    amfree(logfile);
+}
+
+
+int get_logline(logf)
+FILE *logf;
+{
+    static char *logline = NULL;
+    char *logstr, *progstr;
+    char *s;
+    int ch;
+
+    amfree(logline);
+    if((logline = agets(logf)) == NULL) return 0;
+    curlinenum++;
+    s = logline;
+    ch = *s++;
+
+    /* continuation lines are special */
+
+    if(logline[0] == ' ' && logline[1] == ' ') {
+       curlog = L_CONT;
+       /* curprog stays the same */
+       skip_whitespace(s, ch);
+       curstr = s-1;
+       return 1;
+    }
+
+    /* isolate logtype field */
+
+    skip_whitespace(s, ch);
+    logstr = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    /* isolate program name field */
+
+    skip_whitespace(s, ch);
+    progstr = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    /* rest of line is logtype dependent string */
+
+    skip_whitespace(s, ch);
+    curstr = s - 1;
+
+    /* lookup strings */
+
+    for(curlog = L_MARKER; curlog != L_BOGUS; curlog--)
+       if(strcmp(logtype_str[curlog], logstr) == 0) break;
+
+    for(curprog = P_LAST; curprog != P_UNKNOWN; curprog--)
+       if(strcmp(program_str[curprog], progstr) == 0) break;
+
+    return 1;
+}
diff --git a/server-src/logfile.h b/server-src/logfile.h
new file mode 100644 (file)
index 0000000..d229f6e
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: logfile.h,v 1.6.8.1.2.1 2002/02/10 03:31:53 jrjackson Exp $
+ *
+ * interface to logfile module
+ */
+#ifndef LOGFILE_H
+#define LOGFILE_H
+
+#include "amanda.h"
+
+/*
+ * L_FAIL is defined on m88k-motorola-sysv4 systems for multiprocessor
+ * support, which we don't need, so it gets undefined here.
+ */
+#undef L_FAIL
+
+typedef enum logtype_e {
+    L_BOGUS,
+    L_FATAL,           /* program died for some reason, used by error() */
+    L_ERROR, L_WARNING,        L_INFO, L_SUMMARY,       /* information messages */
+    L_START, L_FINISH,                              /* start/end of run */
+    L_DISK,                                                     /* disk */
+    L_SUCCESS, L_FAIL, L_STRANGE,                  /* the end of a dump */
+    L_STATS,                                              /* statistics */
+    L_MARKER,                                    /* marker for reporter */
+    L_CONT                      /* continuation line, used when reading */
+} logtype_t;
+
+typedef enum program_e {
+    P_UNKNOWN, P_PLANNER, P_DRIVER, P_REPORTER, P_DUMPER, P_TAPER, P_AMFLUSH
+} program_t;
+#define P_LAST P_AMFLUSH
+
+extern char *logtype_str[];
+
+extern int curlinenum;
+extern logtype_t curlog;
+extern program_t curprog;
+extern char *curstr;
+extern char *program_str[];
+
+void logerror P((char *));
+void log_add P((logtype_t typ, char * format, ...))
+    __attribute__ ((format (printf, 2, 3)));
+void log_start_multiline P((void));
+void log_end_multiline P((void));
+void log_rename P((char *datestamp));
+int get_logline P((FILE *));
+
+#endif  /* ! LOGFILE_H */
diff --git a/server-src/planner.c b/server-src/planner.c
new file mode 100644 (file)
index 0000000..82522b7
--- /dev/null
@@ -0,0 +1,2504 @@
+/*
+ * 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: planner.c,v 1.76.2.15.2.13.2.35 2004/05/10 16:43:49 martinea Exp $
+ *
+ * backup schedule planner for the Amanda backup system.
+ */
+#include "amanda.h"
+#include "arglist.h"
+#include "conffile.h"
+#include "diskfile.h"
+#include "tapefile.h"
+#include "infofile.h"
+#include "logfile.h"
+#include "clock.h"
+#include "dgram.h"
+#include "protocol.h"
+#include "version.h"
+#include "amfeatures.h"
+#include "server_util.h"
+#include "holding.h"
+
+#define MAX_LEVELS                 3   /* max# of estimates per filesys */
+
+#define RUNS_REDZONE               5   /* should be in conf file? */
+
+#define PROMOTE_THRESHOLD       0.05   /* if <5% unbalanced, don't promote */
+#define DEFAULT_DUMPRATE        30.0   /* K/s */
+
+/* configuration file stuff */
+
+char *conf_tapetype;
+int conf_maxdumpsize;
+int conf_runtapes;
+int conf_dumpcycle;
+int conf_runspercycle;
+int conf_tapecycle;
+int conf_bumpdays;
+int conf_bumpsize;
+int conf_etimeout;
+int conf_reserve;
+int conf_autoflush;
+double conf_bumpmult;
+
+#define HOST_READY                             ((void *)0)     /* must be 0 */
+#define HOST_ACTIVE                            ((void *)1)
+#define HOST_DONE                              ((void *)2)
+
+#define DISK_READY                             0               /* must be 0 */
+#define DISK_ACTIVE                            1
+#define DISK_DONE                              2
+
+typedef struct est_s {
+    int state;
+    int got_estimate;
+    int dump_priority;
+    int dump_level;
+    long dump_size;
+    int degr_level;    /* if dump_level == 0, what would be the inc level */
+    long degr_size;
+    int last_level;
+    long last_lev0size;
+    int next_level0;
+    int level_days;
+    int promote;
+    double fullrate, incrrate;
+    double fullcomp, incrcomp;
+    char *errstr;
+    int level[MAX_LEVELS];
+    char *dumpdate[MAX_LEVELS];
+    long est_size[MAX_LEVELS];
+} est_t;
+
+#define est(dp)        ((est_t *)(dp)->up)
+
+disklist_t startq, waitq, estq, failq, schedq;
+long total_size;
+double total_lev0, balanced_size, balance_threshold;
+unsigned long tape_length, tape_mark;
+int result_port, amanda_port;
+
+static am_feature_t *our_features = NULL;
+static char *our_feature_string = NULL;
+
+#ifdef KRB4_SECURITY
+int kamanda_port;
+#endif
+
+tapetype_t *tape;
+long tt_blocksize;
+long tt_blocksize_kb;
+int runs_per_cycle = 0;
+time_t today;
+
+dgram_t *msg;
+
+/* We keep a LIFO queue of before images for all modifications made
+ * to schedq in our attempt to make the schedule fit on the tape.
+ * Enough information is stored to reinstate a dump if it turns out
+ * that it shouldn't have been touched after all.
+ */
+typedef struct bi_s {
+    struct bi_s *next;
+    struct bi_s *prev;
+    int deleted;               /* 0=modified, 1=deleted */
+    disk_t *dp;                        /* The disk that was changed */
+    int level;                 /* The original level */
+    long size;                 /* The original size */
+    char *errstr;              /* A message describing why this disk is here */
+} bi_t;
+
+typedef struct bilist_s {
+    bi_t *head, *tail;
+} bilist_t;
+
+bilist_t biq;                  /* The BI queue itself */
+
+char *datestamp = NULL;
+
+/*
+ * ========================================================================
+ * MAIN PROGRAM
+ *
+ */
+
+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(argc, argv)
+int argc;
+char **argv;
+{
+    disklist_t *origqp;
+    disk_t *dp;
+    int moved_one;
+    char **vp;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    long initial_size;
+    int fd;
+    char *conffile;
+    char *conf_diskfile;
+    char *conf_tapelist;
+    char *conf_infofile;
+    times_t section_start;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    if (argc > 1) {
+       config_name = stralloc(argv[1]);
+       config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+    } else {
+       char my_cwd[STR_SIZE];
+
+       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+           error("cannot determine current working directory");
+       }
+       config_dir = stralloc2(my_cwd, "/");
+       if ((config_name = strrchr(my_cwd, '/')) != NULL) {
+           config_name = stralloc(config_name + 1);
+       }
+    }
+
+    safe_cd();
+
+    set_pname("planner");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    erroutput_type = (ERR_AMANDALOG|ERR_INTERACTIVE);
+    set_logerror(logerror);
+    startclock();
+    section_start = curclock();
+
+    our_features = am_init_feature_set();
+    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());
+    for(vp = version_info; *vp != NULL; vp++)
+       fprintf(stderr, "%s: %s", get_pname(), *vp);
+
+    /*
+     * 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.
+     */
+
+    /* set up dgram port first thing */
+
+    msg = dgram_alloc();
+
+    if(dgram_bind(msg, &result_port) == -1) {
+       error("could not bind result datagram port: %s", strerror(errno));
+    }
+
+    if(geteuid() == 0) {
+       /* set both real and effective uid's to real uid, likewise for gid */
+       setgid(getgid());
+       setuid(getuid());
+    }
+
+    /*
+     * From this point on we are running under our real uid, so we don't
+     * have to worry about opening security holes below.  Make sure we
+     * are a valid user.
+     */
+
+    if(getpwuid(getuid()) == NULL) {
+       error("can't get login name for my uid %ld", (long)getuid());
+    }
+
+    /*
+     * 2. Read in Configuration Information
+     *
+     * All the Amanda configuration files are loaded before we begin.
+     */
+
+    fprintf(stderr,"READING CONF FILES...\n");
+
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if(read_conffile(conffile)) {
+       error("errors processing config file \"%s\"", conffile);
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((origqp = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist \"%s\"", conf_diskfile);
+    }
+    match_disklist(origqp, argc-2, argv+2);
+    for(dp = origqp->head; dp != NULL; dp = dp->next) {
+       if(dp->todo)
+           log_add(L_DISK, "%s %s", dp->host->hostname, dp->name);
+    }
+    amfree(conf_diskfile);
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+    amfree(conf_tapelist);
+    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)) {
+       error("could not open info db \"%s\"", conf_infofile);
+    }
+    amfree(conf_infofile);
+
+    conf_tapetype = getconf_str(CNF_TAPETYPE);
+    conf_maxdumpsize = getconf_int(CNF_MAXDUMPSIZE);
+    conf_runtapes = getconf_int(CNF_RUNTAPES);
+    conf_dumpcycle = getconf_int(CNF_DUMPCYCLE);
+    conf_runspercycle = getconf_int(CNF_RUNSPERCYCLE);
+    conf_tapecycle = getconf_int(CNF_TAPECYCLE);
+    conf_bumpdays = getconf_int(CNF_BUMPDAYS);
+    conf_bumpsize = getconf_int(CNF_BUMPSIZE);
+    conf_bumpmult = getconf_real(CNF_BUMPMULT);
+    conf_etimeout = getconf_int(CNF_ETIMEOUT);
+    conf_reserve  = getconf_int(CNF_RESERVE);
+    conf_autoflush = getconf_int(CNF_AUTOFLUSH);
+
+    amfree(datestamp);
+    today = time(0);
+    datestamp = construct_datestamp(NULL);
+    log_add(L_START, "date %s", datestamp);
+
+    /* some initializations */
+
+    if(conf_runspercycle == 0) {
+       runs_per_cycle = conf_dumpcycle;
+    } else if(conf_runspercycle == -1 ) {
+       runs_per_cycle = guess_runs_from_tapelist();
+    } else
+       runs_per_cycle = conf_runspercycle;
+
+    if (runs_per_cycle <= 0) {
+       runs_per_cycle = 1;
+    }
+
+    /*
+     * do some basic sanity checking
+     */
+     if(conf_tapecycle <= runs_per_cycle) {
+       log_add(L_WARNING, "tapecycle (%d) <= runspercycle (%d)",
+               conf_tapecycle, runs_per_cycle);
+     }
+    
+    tape = lookup_tapetype(conf_tapetype);
+    if(conf_maxdumpsize > 0) {
+       tape_length = conf_maxdumpsize;
+    }
+    else {
+       tape_length = tape->length * conf_runtapes;
+    }
+    tape_mark   = tape->filemark;
+    tt_blocksize_kb = tape->blocksize;
+    tt_blocksize = tt_blocksize_kb * 1024;
+
+    proto_init(msg->socket, today, 1000); /* XXX handles should eq nhosts */
+
+#ifdef KRB4_SECURITY
+    kerberos_service_init();
+#endif
+
+    fprintf(stderr, "%s: time %s: startup took %s secs\n",
+                   get_pname(),
+                   walltime_str(curclock()),
+                   walltime_str(timessub(curclock(), section_start)));
+
+    /*
+     * 3. Calculate Preliminary Dump Levels
+     *
+     * Before we can get estimates from the remote slave hosts, we make a
+     * first attempt at guessing what dump levels we will be dumping at
+     * based on the curinfo database.
+     */
+
+    fprintf(stderr,"\nSETTING UP FOR ESTIMATES...\n");
+    section_start = curclock();
+
+    startq.head = startq.tail = NULL;
+    while(!empty(*origqp)) {
+       disk_t *dp = dequeue_disk(origqp);
+       if(dp->todo == 1) {
+           setup_estimate(dp);
+       }
+    }
+
+    fprintf(stderr, "%s: time %s: setting up estimates took %s secs\n",
+                   get_pname(),
+                   walltime_str(curclock()),
+                   walltime_str(timessub(curclock(), section_start)));
+
+
+    /*
+     * 4. Get Dump Size Estimates from Remote Client Hosts
+     *
+     * Each host is queried (in parallel) for dump size information on all
+     * of its disks, and the results gathered as they come in.
+     */
+
+    /* go out and get the dump estimates */
+
+    fprintf(stderr,"\nGETTING ESTIMATES...\n");
+    section_start = curclock();
+
+    estq.head = estq.tail = NULL;
+    failq.head = failq.tail = NULL;
+
+    get_estimates();
+
+    fprintf(stderr, "%s: time %s: getting estimates took %s secs\n",
+                   get_pname(),
+                   walltime_str(curclock()),
+                   walltime_str(timessub(curclock(), section_start)));
+
+    /*
+     * At this point, all disks with estimates are in estq, and
+     * all the disks on hosts that didn't respond to our inquiry
+     * are in failq.
+     */
+
+    dump_queue("FAILED", failq, 15, stderr);
+    dump_queue("DONE", estq, 15, stderr);
+
+
+    /*
+     * 5. Analyze Dump Estimates
+     *
+     * Each disk's estimates are looked at to determine what level it
+     * should dump at, and to calculate the expected size and time taking
+     * historical dump rates and compression ratios into account.  The
+     * total expected size is accumulated as well.
+     */
+
+    fprintf(stderr,"\nANALYZING ESTIMATES...\n");
+    section_start = curclock();
+
+                       /* an empty tape still has a label and an endmark */
+    total_size = (tt_blocksize_kb + tape_mark) * 2;
+    total_lev0 = 0.0;
+    balanced_size = 0.0;
+
+    schedq.head = schedq.tail = NULL;
+    while(!empty(estq)) analyze_estimate(dequeue_disk(&estq));
+    while(!empty(failq)) handle_failed(dequeue_disk(&failq));
+
+    /*
+     * At this point, all the disks are on schedq sorted by priority.
+     * The total estimated size of the backups is in total_size.
+     */
+
+    {
+       disk_t *dp;
+
+       fprintf(stderr, "INITIAL SCHEDULE (size %ld):\n", 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);
+       }
+    }
+
+
+    /*
+     * 6. Delay Dumps if Schedule Too Big
+     *
+     * If the generated schedule is too big to fit on the tape, we need to
+     * delay some full dumps to make room.  Incrementals will be done
+     * instead (except for new or forced disks).
+     *
+     * In extreme cases, delaying all the full dumps is not even enough.
+     * If so, some low-priority incrementals will be skipped completely
+     * until the dumps fit on the tape.
+     */
+
+    fprintf(stderr,
+      "\nDELAYING DUMPS IF NEEDED, total_size %ld, tape length %lu mark %lu\n",
+           total_size, tape_length, tape_mark);
+
+    initial_size = total_size;
+
+    delay_dumps();
+
+    /* XXX - why bother checking this? */
+    if(empty(schedq) && total_size < initial_size)
+       error("cannot fit anything on tape, bailing out");
+
+
+    /*
+     * 7. Promote Dumps if Schedule Too Small
+     *
+     * Amanda attempts to balance the full dumps over the length of the
+     * dump cycle.  If this night's full dumps are too small relative to
+     * the other nights, promote some high-priority full dumps that will be
+     * due for the next run, to full dumps for tonight, taking care not to
+     * overflow the tape size.
+     *
+     * This doesn't work too well for small sites.  For these we scan ahead
+     * looking for nights that have an excessive number of dumps and promote
+     * one of them.
+     *
+     * Amanda never delays full dumps just for the sake of balancing the
+     * schedule, so it can take a full cycle to balance the schedule after
+     * a big bump.
+     */
+
+    fprintf(stderr,
+     "\nPROMOTING DUMPS IF NEEDED, total_lev0 %1.0f, balanced_size %1.0f...\n",
+           total_lev0, balanced_size);
+
+    balance_threshold = balanced_size * PROMOTE_THRESHOLD;
+    moved_one = 1;
+    while((balanced_size - total_lev0) > balance_threshold && moved_one)
+       moved_one = promote_highest_priority_incremental();
+
+    moved_one = promote_hills();
+
+    fprintf(stderr, "%s: time %s: analysis took %s secs\n",
+                   get_pname(),
+                   walltime_str(curclock()),
+                   walltime_str(timessub(curclock(), section_start)));
+
+
+    /*
+     * 8. Output Schedule
+     *
+     * The schedule goes to stdout, presumably to driver.  A copy is written
+     * on stderr for the debug file.
+     */
+
+    fprintf(stderr,"\nGENERATING SCHEDULE:\n--------\n");
+
+    if(conf_autoflush) {
+       dumpfile_t file;
+       sl_t *holding_list;
+       sle_t *holding_file;
+       holding_list = get_flush(NULL, datestamp, 0, 0);
+       for(holding_file=holding_list->first; holding_file != NULL;
+                                      holding_file = holding_file->next) {
+           get_dumpfile(holding_file->name, &file);
+           
+           log_add(L_DISK, "%s %s", file.name, file.disk);
+           fprintf(stderr,
+                   "FLUSH %s %s %s %d %s\n",
+                   file.name,
+                   file.disk,
+                   file.datestamp,
+                   file.dumplevel,
+                   holding_file->name);
+           fprintf(stdout,
+                   "FLUSH %s %s %s %d %s\n",
+                   file.name,
+                   file.disk,
+                   file.datestamp,
+                   file.dumplevel,
+                   holding_file->name);
+       }
+       free_sl(holding_list);
+       holding_list = NULL;
+    }
+    fprintf(stderr, "ENDFLUSH\n");
+    fprintf(stdout, "ENDFLUSH\n");
+    fflush(stdout);
+
+    while(!empty(schedq)) output_scheduleline(dequeue_disk(&schedq));
+    fprintf(stderr, "--------\n");
+
+    close_infofile();
+    log_add(L_FINISH, "date %s", datestamp);
+
+    amfree(msg);
+    amfree(datestamp);
+    amfree(config_dir);
+    amfree(config_name);
+    amfree(our_feature_string);
+    am_release_feature_set(our_features);
+    our_features = NULL;
+
+    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 0;
+}
+
+
+\f
+/*
+ * ========================================================================
+ * SETUP FOR ESTIMATES
+ *
+ */
+
+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));
+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 */
+{
+    stats_t *stat;
+
+    if(seq < 0 || seq >= MAX_LEVELS) {
+       error("error [planner askfor: seq out of range 0..%d: %d]",
+             MAX_LEVELS, seq);
+    }
+    if(lev < -1 || lev >= DUMP_LEVELS) {
+       error("error [planner askfor: lev out of range -1..%d: %d]",
+             DUMP_LEVELS, lev);
+    }
+
+    if (lev == -1) {
+       ep->level[seq] = -1;
+       ep->dumpdate[seq] = (char *)0;
+       ep->est_size[seq] = -1;
+       return;
+    }
+
+    ep->level[seq] = lev;
+
+    ep->dumpdate[seq] = stralloc(get_dumpdate(info,lev));
+    malloc_mark(ep->dumpdate[seq]);
+
+    stat = &info->inf[lev];
+    if(stat->date == EPOCH) ep->est_size[seq] = -1;
+    else ep->est_size[seq] = stat->size;
+
+    return;
+}
+
+static void
+setup_estimate(dp)
+     disk_t *dp;
+{
+    est_t *ep;
+    info_t info;
+    int i;
+
+    assert(dp && dp->host);
+    fprintf(stderr, "%s: time %s: setting up estimates for %s:%s\n",
+                   get_pname(), walltime_str(curclock()),
+                   dp->host->hostname, dp->name);
+
+    /* get current information about disk */
+
+    if(get_info(dp->host->hostname, dp->name, &info)) {
+       /* no record for this disk, make a note of it */
+       log_add(L_INFO, "Adding new disk %s:%s.", dp->host->hostname, dp->name);
+    }
+
+    /* setup working data struct for disk */
+
+    ep = alloc(sizeof(est_t));
+    malloc_mark(ep);
+    dp->up = (void *) ep;
+    ep->state = DISK_READY;
+    ep->dump_size = -1;
+    ep->dump_priority = dp->priority;
+    ep->errstr = 0;
+    ep->promote = 0;
+
+    /* calculated fields */
+
+    if(info.command & FORCE_FULL) {
+       /* force a level 0, kind of like a new disk */
+       if(dp->strategy == DS_NOFULL) {
+           /*
+            * XXX - Not sure what it means to force a no-full disk.  The
+            * purpose of no-full is to just dump changes relative to a
+            * stable base, for example root partitions that vary only
+            * slightly from a site-wide prototype.  Only the variations
+            * are dumped.
+            *
+            * If we allow a level 0 onto the Amanda cycle, then we are
+            * hosed when that tape gets re-used next.  Disallow this for
+            * now.
+            */
+           log_add(L_ERROR,
+                   "Cannot force full dump of %s:%s with no-full option.",
+                   dp->host->hostname, dp->name);
+
+           /* clear force command */
+           if(info.command & FORCE_FULL)
+               info.command ^= FORCE_FULL;
+           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));
+           ep->last_level = last_level(&info);
+           ep->next_level0 = next_level0(dp, &info);
+       }
+       else {
+           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);
+       }
+    }
+    else if(dp->strategy == DS_NOFULL) {
+       /* force estimate of level 1 */
+       ep->last_level = 1;
+       ep->next_level0 = next_level0(dp, &info);
+    }
+    else {
+       ep->last_level = last_level(&info);
+       ep->next_level0 = next_level0(dp, &info);
+    }
+
+    /* adjust priority levels */
+
+    if(ep->next_level0 < 0) {
+       fprintf(stderr,"%s:%s overdue %d day%s for level 0\n",
+               dp->host->hostname, dp->name,
+               - 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(info.command & FORCE_FULL)
+       ep->dump_priority += 1;
+    /* else XXX bump up the priority of incrementals that failed last night */
+
+    /* handle external level 0 dumps */
+
+    if(dp->skip_full && dp->strategy != DS_NOINC) {
+       if(ep->next_level0 <= 0) {
+           /* update the date field */
+           info.inf[0].date = today;
+           if(info.command & FORCE_FULL)
+               info.command ^= FORCE_FULL;
+           ep->next_level0 += conf_dumpcycle;
+           ep->last_level = 0;
+           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));
+           log_add(L_INFO, "Skipping full dump of %s:%s today.",
+                   dp->host->hostname, dp->name);
+           fprintf(stderr,"%s:%s lev 0 skipped due to skip-full flag\n",
+                   dp->host->hostname, dp->name);
+           /* 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);
+           log_add(L_SUCCESS, "%s %s %s 0 [skipped: skip-full]",
+                   dp->host->hostname, dp->name, datestamp);
+           return;
+       }
+
+       if(ep->last_level == -1) {
+           /* probably a new disk, but skip-full means no full! */
+           ep->last_level = 0;
+       }
+
+       if(ep->next_level0 == 1) {
+           log_add(L_WARNING, "Skipping full dump of %s:%s tomorrow.",
+                   dp->host->hostname, dp->name);
+       }
+    }
+
+    /* handle "skip-incr" type archives */
+
+    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);
+       /* 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);
+
+       log_add(L_SUCCESS, "%s %s %s 1 [skipped: skip-incr]",
+               dp->host->hostname, dp->name, datestamp);
+       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);
+       ep->next_level0 = 0;
+    }
+
+    if(ep->last_level == 0) ep->level_days = 0;
+    else ep->level_days = runs_at(&info, ep->last_level);
+    ep->last_lev0size = info.inf[0].csize;
+
+    ep->fullrate = perf_average(info.full.rate, 0.0);
+    ep->incrrate = perf_average(info.incr.rate, 0.0);
+
+    ep->fullcomp = perf_average(info.full.comp, dp->comprate[0]);
+    ep->incrcomp = perf_average(info.incr.comp, dp->comprate[1]);
+
+    /* determine which estimates to get */
+
+    i = 0;
+
+    if(dp->strategy == DS_NOINC ||
+       (!dp->skip_full &&
+        (!(info.command & FORCE_BUMP) ||
+         dp->skip_incr ||
+         ep->last_level == -1))){
+
+       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);
+       }
+       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);
+           }
+           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);
+           }
+           
+           break;
+
+       case DS_NOFULL:
+           break;
+
+       case DS_INCRONLY:
+           if (info.command & FORCE_FULL)
+               askfor(ep, i++, 0, &info);
+           break;
+       }
+    }
+
+    if(!dp->skip_incr && !(dp->strategy == DS_NOINC)) {
+       if(ep->last_level == -1) {              /* a new disk */
+           if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY) {
+               askfor(ep, i++, 1, &info);
+           } else {
+               assert(!dp->skip_full);         /* should be handled above */
+           }
+       } else {                                /* not new, pick normally */
+           int curr_level;
+
+           curr_level = ep->last_level;
+
+           if(info.command & FORCE_NO_BUMP) {
+               if(curr_level > 0) { /* level 0 already asked for */
+                   askfor(ep, i++, curr_level, &info);
+               }
+               log_add(L_INFO,"Preventing bump of %s:%s as directed.",
+                       dp->host->hostname, dp->name);
+           }
+           else if((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);
+           }
+           else if(curr_level == 0) {
+               askfor(ep, i++, 1, &info);
+           }
+           else {
+               askfor(ep, i++, curr_level, &info);
+               /*
+                * If last time we dumped less than the threshold, then this
+                * time we will too, OR the extra size will be charged to both
+                * cur_level and cur_level + 1, so we will never bump.  Also,
+                * 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 */
+                   (((info.inf[curr_level].size > bump_thresh(curr_level)))
+                    && ep->level_days >= conf_bumpdays))
+                  && curr_level + 1 < DUMP_LEVELS) {
+                   askfor(ep, i++, curr_level+1, &info);
+               }
+           } 
+       }
+    }
+
+    while(i < MAX_LEVELS)      /* mark end of estimates */
+       askfor(ep, i++, -1, &info);
+
+    /* debug output */
+
+    fprintf(stderr, "setup_estimate: %s:%s: command %d, options:",
+           dp->host->hostname, dp->name, info.command);
+    if(dp->strategy == DS_NOFULL) fputs(" no-full", stderr);
+    if(dp->strategy == DS_INCRONLY) fputs(" incr-only", stderr);
+    if(dp->skip_full) fputs(" skip-full", stderr);
+    if(dp->skip_incr) fputs(" skip-incr", stderr);
+    fprintf(stderr, "\n    last_level %d next_level0 %d level_days %d\n",
+           ep->last_level, ep->next_level0, ep->level_days);
+    fprintf(stderr, "    getting estimates %d (%ld) %d (%ld) %d (%ld)\n",
+           ep->level[0], ep->est_size[0],
+           ep->level[1], ep->est_size[1],
+           ep->level[2], ep->est_size[2]);
+
+    assert(ep->level[0] != -1);
+    enqueue_disk(&startq, dp);
+}
+
+static int when_overwrite(label)
+char *label;
+{
+    tape_t *tp;
+
+    if((tp = lookup_tapelabel(label)) == NULL)
+       return 1;       /* "shouldn't happen", but trigger warning message */
+    else if(!reusable_tape(tp))
+       return 1024;
+    else if(lookup_nb_tape() > conf_tapecycle)
+       return (lookup_nb_tape() - tp->position) / conf_runtapes;
+    else
+       return (conf_tapecycle - tp->position) / conf_runtapes;
+}
+
+/* Return the estimated size for a particular dump */
+static long est_size(dp, level)
+disk_t *dp;
+int level;
+{
+    int i;
+
+    for(i = 0; i < MAX_LEVELS; i++) {
+       if(level == est(dp)->level[i])
+           return est(dp)->est_size[i];
+    }
+    return -1;
+}
+
+/* Return the estimated on-tape size of a particular dump */
+static long est_tape_size(dp, level)
+disk_t *dp;
+int level;
+{
+    long size;
+    double ratio;
+
+    size = est_size(dp, level);
+
+    if(size == -1) return size;
+
+    if(dp->compress == COMP_NONE)
+       return size;
+
+    if(level == 0) ratio = est(dp)->fullcomp;
+    else ratio = est(dp)->incrcomp;
+
+    /*
+     * make sure over-inflated compression ratios don't throw off the
+     * estimates, this is mostly for when you have a small dump getting
+     * compressed which takes up alot more disk/tape space relatively due
+     * to the overhead of the compression.  This is specifically for
+     * Digital Unix vdump.  This patch is courtesy of Rudolf Gabler
+     * (RUG@USM.Uni-Muenchen.DE)
+     */
+
+    if(ratio > 1.1) ratio = 1.1;
+
+    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;
+    }
+
+    return size;
+}
+
+
+/* what was the level of the last successful dump to tape? */
+static int last_level(info)
+info_t *info;
+{
+    int min_pos, min_level, i;
+    time_t lev0_date, last_date;
+    tape_t *tp;
+
+    if(info->last_level != -1)
+       return info->last_level;
+
+    /* to keep compatibility with old infofile */
+    min_pos = 1000000000;
+    min_level = -1;
+    lev0_date = EPOCH;
+    last_date = EPOCH;
+    for(i = 0; i < 9; i++) {
+       if(conf_reserve < 100) {
+           if(i == 0) lev0_date = info->inf[0].date;
+           else if(info->inf[i].date < lev0_date) continue;
+           if(info->inf[i].date > last_date) {
+               last_date = info->inf[i].date;
+               min_level = i;
+           }
+       }
+       else {
+           if((tp = lookup_tapelabel(info->inf[i].label)) == NULL) continue;
+           /* cull any entries from previous cycles */
+           if(i == 0) lev0_date = info->inf[0].date;
+           else if(info->inf[i].date < lev0_date) continue;
+
+           if(tp->position < min_pos) {
+               min_pos = tp->position;
+               min_level = i;
+           }
+       }
+    }
+    info->last_level = i;
+    return min_level;
+}
+
+/* when is next level 0 due? 0 = today, 1 = tomorrow, etc*/
+static int
+next_level0(dp, info)
+     disk_t *dp;
+     info_t *info;
+{
+    if(dp->strategy == DS_NOFULL || dp->strategy == DS_INCRONLY)
+       return 1;               /* fake it */
+    else if (dp->strategy == DS_NOINC)
+       return 0;
+    else if(info->inf[0].date < (time_t)0)
+       return -days_diff(EPOCH, today);        /* new disk */
+    else
+       return dp->dumpcycle - days_diff(info->inf[0].date, today);
+}
+
+/* how many runs at current level? */
+static int runs_at(info, lev)
+info_t *info;
+int lev;
+{
+    tape_t *cur_tape, *old_tape;
+    int last, nb_runs;
+
+    last = last_level(info);
+    if(lev != last) return 0;
+    if(lev == 0) return 1;
+
+    if(info->consecutive_runs != -1)
+       return info->consecutive_runs;
+
+    /* to keep compatibility with old infofile */
+    cur_tape = lookup_tapelabel(info->inf[lev].label);
+    old_tape = lookup_tapelabel(info->inf[lev-1].label);
+    if(cur_tape == NULL || old_tape == NULL) return 0;
+
+    nb_runs = (old_tape->position - cur_tape->position) / conf_runtapes;
+    info->consecutive_runs = nb_runs;
+
+    return nb_runs;
+}
+
+
+static long bump_thresh(level)
+int level;
+{
+    double bump;
+
+    bump = conf_bumpsize;
+    while(--level) bump = bump * conf_bumpmult;
+
+    return (long)bump;
+}
+
+
+\f
+/*
+ * ========================================================================
+ * GET REMOTE DUMP SIZE ESTIMATES
+ *
+ */
+
+static void getsize P((host_t *hostp));
+static disk_t *lookup_hostdisk P((host_t *hp, char *str));
+static void handle_result P((proto_t *p, pkt_t *pkt));
+
+
+static void get_estimates P((void))
+{
+    host_t *hostp;
+    disk_t *dp;
+    struct servent *amandad;
+    int something_started;
+
+    if((amandad = getservbyname(AMANDA_SERVICE_NAME, "udp")) == NULL)
+       amanda_port = AMANDA_SERVICE_DEFAULT;
+    else
+       amanda_port = ntohs(amandad->s_port);
+
+#ifdef KRB4_SECURITY
+    if((amandad = getservbyname(KAMANDA_SERVICE_NAME, "udp")) == NULL)
+       kamanda_port = KAMANDA_SERVICE_DEFAULT;
+    else
+       kamanda_port = ntohs(amandad->s_port);
+#endif
+
+    something_started = 1;
+    while(something_started) {
+       something_started = 0;
+       for(dp = startq.head; dp != NULL; dp = dp->next) {
+           hostp = dp->host;
+           if(hostp->up == HOST_READY) {
+               something_started = 1;
+               getsize(hostp);
+               check_protocol();
+               /*
+                * dp is no longer on startq, so dp->next is not valid
+                * and we have to start all over.
+                */
+               break;
+           }
+       }
+    }
+    run_protocol();
+
+    while(!empty(waitq)) {
+       disk_t *dp = dequeue_disk(&waitq);
+       est(dp)->errstr = "hmm, disk was stranded on waitq";
+       enqueue_disk(&failq, dp);
+    }
+}
+
+static void getsize(hostp)
+host_t *hostp;
+{
+    disklist_t *destqp;
+    disk_t *dp;
+    char *req = NULL, *errstr = NULL;
+    int i, estimates, rc, timeout, disk_state, req_len;
+    char number[NUM_STR_SIZE];
+
+    assert(hostp->disks != NULL);
+
+    if(hostp->up != HOST_READY) {
+       return;
+    }
+
+    /*
+     * The first time through here we send a "noop" request.  This will
+     * return the feature list from the client if it supports that.
+     * If it does not, handle_result() will set the feature list to an
+     * empty structure.  In either case, we do the disks on the second
+     * (and subsequent) pass(es).
+     */
+
+    if(hostp->features != NULL) { /* sendsize service */
+       int has_features = am_has_feature(hostp->features,
+                                         fe_req_options_features);
+       int has_hostname = am_has_feature(hostp->features,
+                                         fe_req_options_hostname);
+       int has_maxdumps = am_has_feature(hostp->features,
+                                         fe_req_options_maxdumps);
+
+       ap_snprintf(number, sizeof(number), "%d", hostp->maxdumps);
+       req = vstralloc("SERVICE ", "sendsize", "\n",
+                       "OPTIONS ",
+                       has_features ? "features=" : "",
+                       has_features ? our_feature_string : "",
+                       has_features ? ";" : "",
+                       has_maxdumps ? "maxdumps=" : "",
+                       has_maxdumps ? number : "",
+                       has_maxdumps ? ";" : "",
+                       has_hostname ? "hostname=" : "",
+                       has_hostname ? hostp->hostname : "",
+                       has_hostname ? ";" : "",
+                       "\n",
+                       NULL);
+       req_len = strlen(req);
+       req_len += 128;                             /* room for SECURITY ... */
+       estimates = 0;
+       for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+           char *s = NULL;
+           int s_len = 0;
+    
+           if(dp->todo == 0) continue;
+    
+           if(est(dp)->state != DISK_READY) {
+               continue;
+           }
+           est(dp)->got_estimate = 0;
+           if(est(dp)->level[0] == -1) {
+               est(dp)->state = DISK_DONE;
+               continue;   /* ignore this disk */
+           }
+    
+           for(i = 0; i < MAX_LEVELS; i++) {
+               char *l;
+               char *exclude1 = "";
+               char *exclude2 = "";
+               char *excludefree = NULL;
+               char spindle[NUM_STR_SIZE];
+               char level[NUM_STR_SIZE];
+               int lev = est(dp)->level[i];
+    
+               if(lev == -1) break;
+    
+               ap_snprintf(level, sizeof(level), "%d", lev);
+               ap_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);
+                   excludefree = exclude2;
+               }
+               else {
+                   if(dp->exclude_file && dp->exclude_file->nb_element == 1) {
+                       exclude1 = " exclude-file=";
+                       exclude2 = dp->exclude_file->first->name;
+                   }
+                   else if(dp->exclude_list
+                           && dp->exclude_list->nb_element == 1) {
+                       exclude1 = " exclude-list=";
+                       exclude2 = dp->exclude_list->first->name;
+                   }
+               }
+               if(dp->device) {
+                   l = vstralloc(dp->program, " ",
+                                 dp->name, " ",
+                                 dp->device, " ",
+                                 level, " ",
+                                 est(dp)->dumpdate[i], " ", spindle,
+                                 exclude1,
+                                 exclude2,
+                                 "\n",
+                                 NULL);
+               }
+               else {
+                   l = vstralloc(dp->program, " ", dp->name, " ", level, " ",
+                                 est(dp)->dumpdate[i], " ", spindle,
+                                 exclude1,
+                                 exclude2,
+                                 "\n",
+                                 NULL);
+               }
+               amfree(excludefree);
+               strappend(s, l);
+               s_len += strlen(l);
+               amfree(l);
+           }
+           /*
+            * Allow 2X for err response.
+            */
+           if(req_len + s_len > MAX_DGRAM / 2) {
+               amfree(s);
+               break;
+           }
+           estimates += i;
+           strappend(req, s);
+           req_len += s_len;
+           amfree(s);
+           est(dp)->state = DISK_ACTIVE;
+           remove_disk(&startq, dp);
+       }
+    
+       if(estimates == 0) {
+           amfree(req);
+           hostp->up = HOST_DONE;
+           return;
+       }
+
+       if (conf_etimeout < 0) {
+           timeout = - conf_etimeout;
+       } else {
+           timeout = estimates * conf_etimeout;
+       }
+    } else { /* noop service */
+       req = vstralloc("SERVICE ", "noop", "\n",
+                       "OPTIONS ",
+                       "features=", our_feature_string, ";",
+                       "\n",
+                       NULL);
+       /*
+        * We use ctimeout for the "noop" request because it should be
+        * very fast and etimeout has other side effects.
+        */
+       timeout = getconf_int(CNF_CTIMEOUT);
+    }
+
+#ifdef KRB4_SECURITY
+    if(hostp->disks->auth == AUTH_KRB4)
+       rc = make_krb_request(hostp->hostname, kamanda_port, req,
+                             hostp, timeout, handle_result);
+    else
+#endif
+       rc = make_request(hostp->hostname, amanda_port, req,
+                         hostp, timeout, handle_result);
+
+    req = NULL;                                        /* do not own this any more */
+
+    if(rc) {
+       errstr = vstralloc("could not resolve hostname \"",
+                          hostp->hostname,
+                          "\"",
+                          NULL);
+       destqp = &failq;
+       hostp->up = HOST_DONE;
+       disk_state = DISK_DONE;
+    }
+    else {
+       errstr = NULL;
+       destqp = &waitq;
+       hostp->up = HOST_ACTIVE;
+       disk_state = DISK_ACTIVE;
+    }
+
+    for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+       if(dp->todo && est(dp)->state == DISK_ACTIVE) {
+           est(dp)->state = disk_state;
+           est(dp)->errstr = errstr;
+           errstr = NULL;
+           enqueue_disk(destqp, dp);
+       }
+    }
+    amfree(errstr);
+}
+
+static disk_t *lookup_hostdisk(hp, str)
+host_t *hp;
+char *str;
+{
+    disk_t *dp;
+
+    for(dp = hp->disks; dp != NULL; dp = dp->hostnext)
+       if(strcmp(str, dp->name) == 0) return dp;
+
+    return NULL;
+}
+
+
+static void handle_result(p, pkt)
+proto_t *p;
+pkt_t *pkt;
+{
+    int level, i;
+    long size;
+    disk_t *dp;
+    host_t *hostp;
+    char *msgdisk=NULL, *msgdisk_undo=NULL, msgdisk_undo_ch = '\0';
+    char *errbuf = NULL;
+    char *line;
+    char *fp;
+    char *s;
+    char *t;
+    int ch;
+    int tch;
+
+    hostp = (host_t *) p->datap;
+    hostp->up = HOST_READY;
+
+    if(p->state == S_FAILED && pkt == NULL) {
+       if(p->prevstate == S_REPWAIT) {
+           errbuf = vstralloc("Estimate timeout from ", hostp->hostname,
+                              NULL);
+       }
+       else {
+           errbuf = vstralloc("Request to ", hostp->hostname, " timed out.",
+                              NULL);
+       }
+       goto error_return;
+    }
+
+#if 0
+    fprintf(stderr, "got %sresponse from %s:\n----\n%s----\n\n",
+           (p->state == S_FAILED) ? "NAK " : "", hostp->hostname, pkt->body);
+#endif
+
+#ifdef KRB4_SECURITY
+    if(hostp->disks->auth == AUTH_KRB4 &&
+       !check_mutual_authenticator(host2key(hostp->hostname), pkt, p)) {
+       errbuf = vstralloc(hostp->hostname,
+                          "[mutual-authentication failed]",
+                          NULL);
+       goto error_return;
+    }
+#endif
+
+    msgdisk_undo = NULL;
+    s = pkt->body;
+    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) {
+#undef sc
+
+#define sc "features="
+           t = strstr(line, sc);
+           if(t != NULL && (isspace((int)t[-1]) || t[-1] == ';')) {
+               t += sizeof(sc)-1;
+#undef sc
+               am_release_feature_set(hostp->features);
+               if((hostp->features = am_string_to_feature(t)) == NULL) {
+                   errbuf = vstralloc(hostp->hostname,
+                                      ": bad features value: ",
+                                      line,
+                                      "\n",
+                                      NULL);
+                   goto error_return;
+               }
+           }
+
+           continue;
+       }
+
+#define sc "ERROR "
+       if(strncmp(line, sc, sizeof(sc)-1) == 0) {
+           t = line + sizeof(sc)-1;
+           tch = t[-1];
+#undef sc
+
+           fp = t - 1;
+           skip_whitespace(t, tch);
+           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).
+            * We can ignore this.
+            */
+           if(hostp->features == NULL
+              && p->state == S_FAILED
+              && (strcmp(t - 1, "unknown service: noop") == 0
+                  || strcmp(t - 1, "noop: invalid service") == 0)) {
+               continue;
+           } else {
+               errbuf = vstralloc(hostp->hostname,
+                                  (p->state == S_FAILED) ? "NAK " : "",
+                                  ": ",
+                                  fp,
+                                  NULL);
+               goto error_return;
+           }
+       }
+
+       msgdisk = t = line;
+       tch = *t++;
+       skip_non_whitespace(t, tch);
+       msgdisk_undo = t - 1;
+       msgdisk_undo_ch = *msgdisk_undo;
+       *msgdisk_undo = '\0';
+
+       skip_whitespace(t, tch);
+       if (sscanf(t - 1, "%d SIZE %ld", &level, &size) != 2) {
+           goto bad_msg;
+       }
+
+       dp = lookup_hostdisk(hostp, msgdisk);
+
+       *msgdisk_undo = msgdisk_undo_ch;        /* for error message */
+       msgdisk_undo = NULL;
+
+       if(dp == NULL) {
+           log_add(L_ERROR, "%s: invalid reply from sendsize: `%s'\n",
+                   hostp->hostname, line);
+       } else {
+           for(i = 0; i < MAX_LEVELS; i++) {
+               if(est(dp)->level[i] == level) {
+                   est(dp)->est_size[i] = size;
+                   break;
+               }
+           }
+           if(i == MAX_LEVELS) {
+               goto bad_msg;                   /* this est wasn't requested */
+           }
+           est(dp)->got_estimate++;
+       }
+    }
+
+    if(hostp->up == HOST_READY && hostp->features == NULL) {
+       /*
+        * The client does not support the features list, so give it an
+        * empty one.
+        */
+       dbprintf(("%s: no feature set from host %s\n",
+                 debug_prefix_time(NULL), hostp->hostname));
+       hostp->features = am_set_default_feature_set();
+    }
+
+    /* XXX what about disks that only got some estimates...  do we care? */
+    /* XXX amanda 2.1 treated that case as a bad msg */
+
+    for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+       if(dp->todo == 0) continue;
+       if(est(dp)->state != DISK_ACTIVE) continue;
+       est(dp)->state = DISK_DONE;
+       if(est(dp)->level[0] == -1) continue;   /* ignore this disk */
+       remove_disk(&waitq, dp);
+       if(est(dp)->got_estimate) {
+           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) {
+                   log_add(L_WARNING,
+                           "disk %s:%s, estimate of level %d failed: %d.",
+                           dp->host->hostname, dp->name,
+                           est(dp)->level[2], est(dp)->est_size[2]);
+                   est(dp)->level[2] = -1;
+               }
+               if(est(dp)->level[1] != -1 && est(dp)->est_size[1] < 0) {
+                   log_add(L_WARNING,
+                           "disk %s:%s, estimate of level %d failed: %d.",
+                           dp->host->hostname, dp->name,
+                           est(dp)->level[1], est(dp)->est_size[1]);
+                   est(dp)->level[1] = -1;
+               }
+               if(est(dp)->level[0] != -1 && est(dp)->est_size[0] < 0) {
+                   log_add(L_WARNING,
+                           "disk %s:%s, estimate of level %d failed: %d.",
+                           dp->host->hostname, dp->name,
+                           est(dp)->level[0], est(dp)->est_size[0]);
+                   est(dp)->level[0] = -1;
+               }
+
+               enqueue_disk(&estq, dp);
+           }
+           else {
+               enqueue_disk(&failq, dp);
+               est(dp)->errstr = vstralloc("disk ", dp->name,
+                                           ", all estimate failed", NULL);
+           }
+       }
+       else {
+           enqueue_disk(&failq, dp);
+
+           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,
+                                       " in ", dp->host->hostname, " response",
+                                       NULL);
+       }
+    }
+    getsize(hostp);
+    return;
+
+ bad_msg:
+
+    if(msgdisk_undo) {
+       *msgdisk_undo = msgdisk_undo_ch;
+       msgdisk_undo = NULL;
+    }
+    fprintf(stderr,"got a bad message, stopped at:\n");
+    fprintf(stderr,"----\n%s\n----\n\n", line);
+    errbuf = stralloc2("badly formatted response from ", hostp->hostname);
+    /* fall through to ... */
+
+ error_return:
+
+    if(msgdisk_undo) {
+       *msgdisk_undo = msgdisk_undo_ch;
+       msgdisk_undo = NULL;
+    }
+    i = 0;
+    for(dp = hostp->disks; dp != NULL; dp = dp->hostnext) {
+       if(est(dp)->state == DISK_ACTIVE) {
+           est(dp)->state = DISK_DONE;
+           remove_disk(&waitq, dp);
+           enqueue_disk(&failq, dp);
+           i++;
+
+           est(dp)->errstr = stralloc(errbuf);
+           fprintf(stderr, "%s: time %s: error result for host %s disk %s: %s\n",
+               get_pname(), walltime_str(curclock()),
+               dp->host->hostname, dp->name, errbuf);
+       }
+    }
+    if(i == 0) {
+       /*
+        * If there were no disks involved, make sure the error gets
+        * reported.
+        */
+       log_add(L_ERROR, "%s", errbuf);
+    }
+    hostp->up = HOST_DONE;
+    amfree(errbuf);
+}
+
+
+
+\f
+/*
+ * ========================================================================
+ * ANALYSE ESTIMATES
+ *
+ */
+
+static int schedule_order P((disk_t *a, disk_t *b));     /* subroutines */
+static int pick_inclevel P((disk_t *dp));
+
+static void analyze_estimate(dp)
+disk_t *dp;
+{
+    est_t *ep;
+    info_t info;
+    int have_info = 0;
+
+    ep = est(dp);
+
+    fprintf(stderr, "pondering %s:%s... ",
+           dp->host->hostname, dp->name);
+    fprintf(stderr, "next_level0 %d last_level %d ",
+           ep->next_level0, ep->last_level);
+
+    if(get_info(dp->host->hostname, dp->name, &info) == 0) {
+       have_info = 1;
+    }
+
+    ep->degr_level = -1;
+    ep->degr_size = -1;
+
+    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) {
+           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);
+
+           if(ep->dump_size == -1) {
+               ep->dump_level = ep->dump_level + 1;
+               ep->dump_size = est_tape_size(dp, ep->dump_level);
+           }
+       }
+       else {
+           total_lev0 += (double) ep->dump_size;
+           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;
+           }
+           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_level = ep->degr_level + 1;
+                   ep->degr_size = est_tape_size(dp, ep->degr_level);
+               }
+               if(ep->degr_size == -1) {
+                   fprintf(stderr,"(no inc estimate)");
+                   ep->degr_level = -1;
+               }
+               fprintf(stderr,"\n");
+           }
+       }
+    }
+    else {
+       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);
+
+       if(ep->dump_size == -1) {
+           ep->dump_level = ep->last_level;
+           ep->dump_size = est_tape_size(dp, ep->dump_level);
+       }
+       if(ep->dump_size == -1) {
+           ep->dump_level = ep->last_level + 1;
+           ep->dump_size = est_tape_size(dp, ep->dump_level);
+       }
+       if(ep->dump_size == -1) {
+           ep->dump_level = 0;
+           ep->dump_size = est_tape_size(dp, ep->dump_level);
+       }
+    }
+
+    fprintf(stderr,"  curr level %d size %ld ", ep->dump_level, ep->dump_size);
+
+    insert_disk(&schedq, dp, schedule_order);
+
+    total_size += tt_blocksize_kb + ep->dump_size + tape_mark;
+
+    /* update the balanced size */
+    if(!(dp->skip_full || dp->strategy == DS_NOFULL || 
+        dp->strategy == DS_INCRONLY)) {
+       long lev0size;
+
+       lev0size = est_tape_size(dp, 0);
+       if(lev0size == -1) lev0size = ep->last_lev0size;
+
+       balanced_size += lev0size / runs_per_cycle;
+    }
+
+    fprintf(stderr,"total size %ld total_lev0 %1.0f balanced-lev0size %1.0f\n",
+           total_size, total_lev0, balanced_size);
+}
+
+static void handle_failed(dp)
+disk_t *dp;
+{
+    char *errstr;
+
+/*
+ * From George Scott <George.Scott@cc.monash.edu.au>:
+ * --------
+ * If a machine is down when the planner is run it guesses from historical
+ * data what the size of tonights dump is likely to be and schedules a
+ * dump anyway.  The dumper then usually discovers that that machine is
+ * still down and ends up with a half full tape.  Unfortunately the
+ * planner had to delay another dump because it thought that the tape was
+ * full.  The fix here is for the planner to ignore unavailable machines
+ * rather than ignore the fact that they are unavailable.
+ * --------
+ */
+
+#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);
+       analyze_estimate(dp);
+       return;
+    }
+#endif
+
+    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);
+
+    log_add(L_FAIL, "%s %s %s 0 [%s]", dp->host->hostname, dp->name, datestamp, errstr);
+
+    /* 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.
+ */
+{
+    int diff;
+    long 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;
+    return 0;
+}
+
+
+static int pick_inclevel(dp)
+disk_t *dp;
+{
+    int base_level, bump_level;
+    long base_size, bump_size;
+    long thresh;
+
+    base_level = est(dp)->last_level;
+
+    /* if last night was level 0, do level 1 tonight, no ifs or buts */
+    if(base_level == 0) {
+       fprintf(stderr,"   picklev: last night 0, so tonight level 1\n");
+       return 1;
+    }
+
+    /* if no-full option set, always do level 1 */
+    if(dp->strategy == DS_NOFULL) {
+       fprintf(stderr,"   picklev: no-full set, so always level 1\n");
+       return 1;
+    }
+
+    base_size = est_size(dp, base_level);
+
+    /* if we didn't get an estimate, we can't do an inc */
+    if(base_size == -1) {
+       base_size = est_size(dp, base_level+1);
+       if(base_size > 0) /* FORCE_BUMP */
+           return base_level+1;
+       fprintf(stderr,"   picklev: no estimate for level %d, so no incs\n", base_level);
+       return base_level;
+    }
+
+    thresh = bump_thresh(base_level);
+
+    fprintf(stderr,
+           "   pick: size %ld level %d days %d (thresh %ldK, %d days)\n",
+           base_size, base_level, est(dp)->level_days,
+           thresh, conf_bumpdays);
+
+    if(base_level == 9
+       || est(dp)->level_days < conf_bumpdays
+       || base_size <= thresh)
+           return base_level;
+
+    bump_level = base_level + 1;
+    bump_size = est_size(dp, bump_level);
+
+    if(bump_size == -1) return base_level;
+
+    fprintf(stderr, "   pick: next size %ld... ", bump_size);
+
+    if(base_size - bump_size < thresh) {
+       fprintf(stderr, "not bumped\n");
+       return base_level;
+    }
+
+    fprintf(stderr, "BUMPED\n");
+    log_add(L_INFO, "Incremental of %s:%s bumped to level %d.",
+           dp->host->hostname, dp->name, bump_level);
+
+    return bump_level;
+}
+
+
+
+\f
+/*
+** ========================================================================
+** ADJUST SCHEDULE
+**
+** We have two strategies here:
+**
+** 1. Delay dumps
+**
+** If we are trying to fit too much on the tape something has to go.  We
+** try to delay totals until tomorrow by converting them into incrementals
+** and, if that is not effective enough, dropping incrementals altogether.
+** While we are searching for the guilty dump (the one that is really
+** causing the schedule to be oversize) we have probably trampled on a lot of
+** innocent dumps, so we maintain a "before image" list and use this to
+** put back what we can.
+**
+** 2. Promote dumps.
+**
+** We try to keep the amount of tape used by total dumps the same each night.
+** If there is some spare tape in this run we have a look to see if any of
+** tonights incrementals could be promoted to totals and leave us with a
+** more balanced cycle.
+*/
+
+static void delay_one_dump P((disk_t *dp, int delete, ...));
+
+static void delay_dumps P((void))
+/* delay any dumps that will not fit */
+{
+    disk_t *dp, *ndp, *preserve;
+    bi_t *bi, *nbi;
+    long new_total;    /* New total_size */
+    char est_kb[20];     /* Text formatted dump size */
+    int nb_forced_level_0;
+    info_t info;
+
+    biq.head = biq.tail = NULL;
+
+    /*
+    ** 1. Delay dumps that are way oversize.
+    **
+    ** Dumps larger that the size of the tapes we are using are just plain
+    ** not going to fit no matter how many other dumps we drop.  Delay
+    ** oversize totals until tomorrow (by which time my owner will have
+    ** resolved the problem!) and drop incrementals altogether.  Naturally
+    ** a large total might be delayed into a large incremental so these
+    ** need to be checked for separately.
+    */
+
+    for(dp = schedq.head; dp != NULL; dp = ndp) {
+       ndp = dp->next; /* remove_disk zaps this */
+
+       if (est(dp)->dump_size <= tape->length) {
+           continue;
+       }
+
+        /* Format dumpsize for messages */
+       ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+
+       if(est(dp)->dump_level == 0) {
+           if(est(dp)->last_level == -1 || dp->skip_incr) {
+               delay_one_dump(dp, 1,
+                              "dump larger than tape,",
+                              est_kb,
+                              "but cannot incremental dump",
+                              dp->skip_incr ? "skip-incr": "new",
+                              "disk",
+                              NULL);
+           }
+           else {
+               delay_one_dump(dp, 0,
+                              "dump larger than tape,",
+                              est_kb,
+                              "full dump delayed",
+                              NULL);
+           }
+       }
+       else {
+           delay_one_dump(dp, 1,
+                          "dump larger than tape,",
+                          est_kb,
+                          "skipping incremental",
+                          NULL);
+       }
+    }
+
+    /*
+    ** 2. Delay total dumps.
+    **
+    ** Delay total dumps until tomorrow (or the day after!).  We start with
+    ** the lowest priority (most dispensable) and work forwards.  We take
+    ** care not to delay *all* the dumps since this could lead to a stale
+    ** mate [for any one disk there are only three ways tomorrows dump will
+    ** be smaller than todays: 1. we do a level 0 today so tomorows dump
+    ** will be a level 1; 2. the disk gets more data so that it is bumped
+    ** tomorrow (this can be a slow process); and, 3. the disk looses some
+    ** data (when does that ever happen?)].
+    */
+
+    nb_forced_level_0 = 0;
+    preserve = NULL;
+    for(dp = schedq.head; dp != NULL && preserve == NULL; dp = dp->next)
+       if(est(dp)->dump_level == 0)
+           preserve = dp;
+
+    /* 2.a. Do not delay forced full */
+    for(dp = schedq.tail;
+               dp != NULL && total_size > tape_length;
+               dp = ndp) {
+       ndp = dp->prev;
+
+       if(est(dp)->dump_level != 0) continue;
+
+       get_info(dp->host->hostname, dp->name, &info);
+       if(info.command & FORCE_FULL) {
+           nb_forced_level_0 += 1;
+           preserve = dp;
+           continue;
+       }
+
+       if(dp != preserve) {
+
+            /* Format dumpsize for messages */
+           ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+
+           if(est(dp)->last_level == -1 || dp->skip_incr) {
+               delay_one_dump(dp, 1,
+                              "dumps too big,",
+                              est_kb,
+                              "but cannot incremental dump",
+                              dp->skip_incr ? "skip-incr": "new",
+                              "disk",
+                              NULL);
+           }
+           else {
+               delay_one_dump(dp, 0,
+                              "dumps too big,",
+                              est_kb,
+                              "full dump delayed",
+                              NULL);
+           }
+       }
+    }
+
+    /* 2.b. Delay forced full if needed */
+    if(nb_forced_level_0 > 0 && total_size > tape_length) {
+       for(dp = schedq.tail;
+               dp != NULL && total_size > tape_length;
+               dp = ndp) {
+           ndp = dp->prev;
+
+           if(est(dp)->dump_level == 0 && dp != preserve) {
+
+               /* Format dumpsize for messages */
+               ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+
+               if(est(dp)->last_level == -1 || dp->skip_incr) {
+                   delay_one_dump(dp, 1,
+                                  "dumps too big,",
+                                  est_kb,
+                                  "but cannot incremental dump",
+                                  dp->skip_incr ? "skip-incr": "new",
+                                  "disk",
+                                  NULL);
+               }
+               else {
+                   delay_one_dump(dp, 0,
+                                  "dumps too big,",
+                                  est_kb,
+                                  "full dump delayed",
+                                  NULL);
+               }
+           }
+       }
+    }
+
+    /*
+    ** 3. Delay incremental dumps.
+    **
+    ** Delay incremental dumps until tomorrow.  This is a last ditch attempt
+    ** at making things fit.  Again, we start with the lowest priority (most
+    ** dispensable) and work forwards.
+    */
+
+    for(dp = schedq.tail;
+           dp != NULL && total_size > tape_length;
+           dp = ndp) {
+       ndp = dp->prev;
+
+       if(est(dp)->dump_level != 0) {
+
+            /* Format dumpsize for messages */
+           ap_snprintf(est_kb, 20, "%ld KB,", est(dp)->dump_size);
+
+           delay_one_dump(dp, 1,
+                          "dumps way too big,",
+                          est_kb,
+                          "must skip incremental dumps",
+                          NULL);
+       }
+    }
+
+    /*
+    ** 4. Reinstate delayed dumps.
+    **
+    ** We might not have needed to stomp on all of the dumps we have just
+    ** delayed above.  Try to reinstate them all starting with the last one
+    ** and working forwards.  It is unlikely that the last one will fit back
+    ** in but why complicate the code?
+    */
+
+    for(bi = biq.tail; bi != NULL; bi = nbi) {
+       nbi = bi->prev;
+       dp = bi->dp;
+
+       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(new_total <= tape_length && bi->size < tape->length) {
+           /* reinstate it */
+           total_size = new_total;
+           if(bi->deleted) {
+               if(bi->level == 0) {
+                   total_lev0 += (double) bi->size;
+               }
+               insert_disk(&schedq, dp, schedule_order);
+           }
+           else {
+               est(dp)->dump_level = bi->level;
+               est(dp)->dump_size = bi->size;
+           }
+
+           /* Keep it clean */
+           if(bi->next == NULL)
+               biq.tail = bi->prev;
+           else
+               (bi->next)->prev = bi->prev;
+           if(bi->prev == NULL)
+               biq.head = bi->next;
+           else
+               (bi->prev)->next = bi->next;
+           amfree(bi->errstr);
+           amfree(bi);
+       }
+    }
+
+    /*
+    ** 5. Output messages about what we have done.
+    **
+    ** We can't output messages while we are delaying dumps because we might
+    ** reinstate them later.  We remember all the messages and output them
+    ** now.
+    */
+
+    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);
+       }
+       else {
+           dp = bi->dp;
+           fprintf(stderr, "  delay: %s now at level %d\n",
+               bi->errstr, est(dp)->dump_level);
+           log_add(L_INFO, "%s", bi->errstr);
+       }
+
+       /* Clean up - dont be too fancy! */
+       amfree(bi->errstr);
+       amfree(bi);
+    }
+
+    fprintf(stderr, "  delay: Total size now %ld.\n", total_size);
+
+    return;
+}
+
+
+/*
+ * 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)
+{
+    bi_t *bi;
+    va_list argp;
+    char level_str[NUM_STR_SIZE];
+    char *sep;
+    char *next;
+
+    arglist_start(argp, delete);
+
+    total_size -= tt_blocksize_kb + est(dp)->dump_size + tape_mark;
+    if(est(dp)->dump_level == 0) {
+       total_lev0 -= (double) est(dp)->dump_size;
+    }
+
+    bi = alloc(sizeof(bi_t));
+    bi->next = NULL;
+    bi->prev = biq.tail;
+    if(biq.tail == NULL)
+       biq.head = bi;
+    else
+       biq.tail->next = bi;
+    biq.tail = bi;
+
+    bi->deleted = delete;
+    bi->dp = dp;
+    bi->level = est(dp)->dump_level;
+    bi->size = est(dp)->dump_size;
+
+    ap_snprintf(level_str, sizeof(level_str), "%d", est(dp)->dump_level);
+    bi->errstr = vstralloc(dp->host->hostname,
+                          " ", dp->name,
+                          " ", datestamp ? datestamp : "?",
+                          " ", level_str,
+                          NULL);
+    sep = " [";
+    while ((next = arglist_val(argp, char *)) != NULL) {
+       bi->errstr = newvstralloc(bi->errstr, bi->errstr, sep, next, NULL);
+       sep = " ";
+    }
+    strappend(bi->errstr, "]");
+    arglist_end(argp);
+
+    if (delete) {
+       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;
+    }
+
+    return;
+}
+
+
+static int promote_highest_priority_incremental P((void))
+{
+    disk_t *dp, *dp1, *dp_promote;
+    long 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;
+
+    /*
+     * return 1 if did so; must update total_size correctly; must not
+     * cause total_size to exceed tape_length
+     */
+
+    dp_promote = NULL;
+    for(dp = schedq.head; dp != NULL; dp = dp->next) {
+
+       est(dp)->promote = -1000;
+
+       if(est_size(dp,0) <= 0)
+           continue;
+
+       if(est(dp)->next_level0 <= 0)
+           continue;
+
+       if(est(dp)->next_level0 > dp->maxpromoteday)
+           continue;
+
+       new_size = est_tape_size(dp, 0);
+       new_total = total_size - est(dp)->dump_size + new_size;
+       new_lev0 = 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) {
+           if(est(dp1)->dump_level == 0)
+               nb_disk_today++;
+           else if(est(dp1)->next_level0 == est(dp)->next_level0)
+               nb_disk_same_day++;
+           if(strcmp(dp->host->hostname, dp1->host->hostname) == 0) {
+               if(est(dp1)->dump_level == 0)
+                   nb_today++;
+               else if(est(dp1)->next_level0 == est(dp)->next_level0)
+                   nb_same_day++;
+           }
+       }
+
+       /* do not promote if overflow tape */
+       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)
+           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;
+
+       nb_today2 = nb_today*nb_today;
+       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)) + 
+                              conf_dumpcycle - est(dp)->next_level0;
+       }
+       else {
+           est(dp)->promote = -nb_today2 +
+                              conf_dumpcycle - est(dp)->next_level0;
+       }
+
+        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);
+       }
+        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);
+       }
+    }
+
+    if(dp_promote) {
+       dp = dp_promote;
+
+       new_size = est_tape_size(dp, 0);
+       new_total = total_size - est(dp)->dump_size + new_size;
+       new_lev0 = total_lev0 + new_size;
+
+       total_size = new_total;
+       total_lev0 = 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)->dump_level = 0;
+       est(dp)->dump_size = new_size;
+       est(dp)->next_level0 = 0;
+
+       fprintf(stderr,
+             "   promote: moving %s:%s up, total_lev0 %1.0f, total_size %ld\n",
+               dp->host->hostname, dp->name,
+               total_lev0, total_size);
+
+       log_add(L_INFO,
+               "Full dump of %s:%s promoted from %d day%s ahead.",
+               dp->host->hostname, dp->name,
+               check_days, (check_days == 1) ? "" : "s");
+       return 1;
+    }
+    return 0;
+}
+
+
+static int promote_hills P((void))
+{
+    disk_t *dp;
+    struct balance_stats {
+       int disks;
+       long size;
+    } *sp = NULL;
+    int tapecycle;
+    int days;
+    int hill_days = 0;
+    long hill_size;
+    long new_size;
+    long new_total;
+
+    /* If we are already doing a level 0 don't bother */
+    if(total_lev0 > 0)
+       return 0;
+
+    /* Do the guts of an "amadmin balance" */
+    tapecycle = conf_tapecycle;
+
+    sp = (struct balance_stats *)
+       alloc(sizeof(struct balance_stats) * tapecycle);
+
+    for(days = 0; days < tapecycle; days++)
+       sp[days].disks = sp[days].size = 0;
+
+    for(dp = schedq.head; dp != NULL; dp = dp->next) {
+       days = est(dp)->next_level0;   /* This is > 0 by definition */
+       if(days<tapecycle && !dp->skip_full && dp->strategy != DS_NOFULL &&
+          dp->strategy != DS_INCRONLY) {
+           sp[days].disks++;
+           sp[days].size += est(dp)->last_lev0size;
+       }
+    }
+
+    /* Search for a suitable big hill and cut it down */
+    while(1) {
+       /* Find the tallest hill */
+       hill_size = 0;
+       for(days = 0; days < tapecycle; days++) {
+           if(sp[days].disks > 1 && sp[days].size > hill_size) {
+               hill_size = sp[days].size;
+               hill_days = days;
+           }
+       }
+
+       if(hill_size <= 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) {
+           if(est(dp)->next_level0 != hill_days ||
+              est(dp)->next_level0 > dp->maxpromoteday ||
+              dp->skip_full ||
+              dp->strategy == DS_NOFULL ||
+              dp->strategy == DS_INCRONLY)
+               continue;
+           new_size = est_tape_size(dp, 0);
+           new_total = total_size - est(dp)->dump_size + new_size;
+           if(new_total > tape_length)
+               continue;
+           /* We found a disk we can promote */
+           total_size = new_total;
+           total_lev0 += new_size;
+           est(dp)->degr_level = est(dp)->dump_level;
+           est(dp)->degr_size = est(dp)->dump_size;
+           est(dp)->dump_level = 0;
+           est(dp)->next_level0 = 0;
+           est(dp)->dump_size = new_size;
+
+           fprintf(stderr,
+                   "   promote: moving %s:%s up, total_lev0 %1.0f, total_size %ld\n",
+                   dp->host->hostname, dp->name,
+                   total_lev0, total_size);
+
+           log_add(L_INFO,
+                   "Full dump of %s:%s specially promoted from %d day%s ahead.",
+                   dp->host->hostname, dp->name,
+                   hill_days, (hill_days == 1) ? "" : "s");
+
+           amfree(sp);
+           return 1;
+       }
+       /* All the disks in that hill were unsuitable. */
+       sp[hill_days].disks = 0;        /* Don't get tricked again */
+    }
+
+    amfree(sp);
+    return 0;
+}
+
+/*
+ * ========================================================================
+ * OUTPUT SCHEDULE
+ *
+ * XXX - memory leak - we shouldn't just throw away *dp
+ */
+static void output_scheduleline(dp)
+    disk_t *dp;
+{
+    est_t *ep;
+    long dump_time = 0, degr_time = 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_time_str[NUM_STR_SIZE];
+    char degr_level_str[NUM_STR_SIZE];
+    char degr_size_str[NUM_STR_SIZE];
+    char degr_time_str[NUM_STR_SIZE];
+    char *dump_date, *degr_date;
+    char *features;
+    int i;
+
+    ep = est(dp);
+
+    if(ep->dump_size == -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);
+       log_add(L_FAIL, "%s %s %s %d [no estimate]",
+               dp->host->hostname, dp->name, datestamp, ep->dump_level);
+       return;
+    }
+
+    dump_date = degr_date = (char *)0;
+    for(i = 0; i < MAX_LEVELS; i++) {
+       if(ep->dump_level == ep->level[i])
+           dump_date = ep->dumpdate[i];
+       if(ep->degr_level == ep->level[i])
+           degr_date = ep->dumpdate[i];
+    }
+
+#define fix_rate(rate) (rate < 1.0 ? DEFAULT_DUMPRATE : rate)
+
+    if(ep->dump_level == 0) {
+       dump_time = ep->dump_size / fix_rate(ep->fullrate);
+
+       if(ep->degr_size != -1) {
+           degr_time = ep->degr_size / fix_rate(ep->incrrate);
+       }
+    }
+    else {
+       dump_time = ep->dump_size / fix_rate(ep->incrrate);
+    }
+
+    if(ep->dump_level == 0 && ep->degr_size != -1) {
+       ap_snprintf(degr_level_str, sizeof(degr_level_str),
+                   "%d", ep->degr_level);
+       ap_snprintf(degr_size_str, sizeof(degr_size_str),
+                   "%ld", ep->degr_size);
+       ap_snprintf(degr_time_str, sizeof(degr_time_str),
+                   "%ld", degr_time);
+       degr_str = vstralloc(" ", degr_level_str,
+                            " ", degr_date,
+                            " ", degr_size_str,
+                            " ", degr_time_str,
+                            NULL);
+    }
+    ap_snprintf(dump_priority_str, sizeof(dump_priority_str),
+               "%d", ep->dump_priority);
+    ap_snprintf(dump_level_str, sizeof(dump_level_str),
+               "%d", ep->dump_level);
+    ap_snprintf(dump_size_str, sizeof(dump_size_str),
+               "%ld", ep->dump_size);
+    ap_snprintf(dump_time_str, sizeof(dump_time_str),
+               "%ld", dump_time);
+    features = am_feature_to_string(dp->host->features);
+    schedline = vstralloc("DUMP ",dp->host->hostname,
+                         " ", features,
+                         " ", dp->name,
+                         " ", datestamp,
+                         " ", dump_priority_str,
+                         " ", dump_level_str,
+                         " ", dump_date,
+                         " ", dump_size_str,
+                         " ", dump_time_str,
+                         degr_str ? degr_str : "",
+                         "\n", NULL);
+
+    fputs(schedline, stdout);
+    fputs(schedline, stderr);
+    amfree(features);
+    amfree(schedline);
+    amfree(degr_str);
+}
diff --git a/server-src/reporter.c b/server-src/reporter.c
new file mode 100644 (file)
index 0000000..96bf404
--- /dev/null
@@ -0,0 +1,2177 @@
+/*
+ * 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.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: reporter.c,v 1.44.2.17.4.6.2.16 2003/11/26 16:10:23 martinea Exp $
+ *
+ * nightly Amanda Report generator
+ */
+/*
+report format
+    tape label message
+    error messages
+    summary stats
+    details for errors
+    notes
+    success summary
+*/
+
+#include "amanda.h"
+#include "conffile.h"
+#include "tapefile.h"
+#include "diskfile.h"
+#include "infofile.h"
+#include "logfile.h"
+#include "version.h"
+#include "util.h"
+
+/* don't have (or need) a skipped type except internally to reporter */
+#define L_SKIPPED      L_MARKER
+
+typedef struct line_s {
+    struct line_s *next;
+    char *str;
+} line_t;
+
+typedef struct timedata_s {
+    logtype_t result;
+    float origsize, outsize;
+    char *datestamp;
+    float sec, kps;
+    int filenum;
+    char *tapelabel;
+} timedata_t;
+
+typedef struct repdata_s {
+    disk_t *disk;
+    char *datestamp;
+    timedata_t taper;
+    timedata_t dumper;
+    int level;
+    struct repdata_s *next;
+} repdata_t;
+
+#define data(dp) ((repdata_t *)(dp)->up)
+
+struct cumulative_stats {
+    int dumpdisks, tapedisks;
+    double taper_time, dumper_time;
+    double outsize, origsize, tapesize;
+    double coutsize, corigsize;                        /* compressed dump only */
+} stats[3];
+
+int dumpdisks[10], tapedisks[10];      /* by-level breakdown of disk count */
+
+typedef struct taper_s {
+    char *label;
+    double taper_time;
+    double coutsize, corigsize;
+    int tapedisks;
+    struct taper_s *next;
+} taper_t;
+
+taper_t *stats_by_tape = NULL;
+taper_t *current_tape = NULL;
+
+float total_time, startup_time;
+
+/* count files to tape */
+int tapefcount = 0;
+
+char *run_datestamp;
+char *today_datestamp;
+char *tape_labels = NULL;
+int last_run_tapes = 0;
+static int degraded_mode = 0; /* defined in driverio too */
+int normal_run = 0;
+int amflush_run = 0;
+int got_finish = 0;
+
+char *tapestart_error = NULL;
+
+FILE *logfile, *mailf;
+
+FILE *postscript;
+char *printer;
+
+disklist_t *diskq;
+disklist_t sortq;
+
+line_t *errsum = NULL;
+line_t *errdet = NULL;
+line_t *notes = NULL;
+
+static char MaxWidthsRequested = 0;    /* determined via config data */
+
+/*
+char *hostname = NULL, *diskname = NULL;
+*/
+
+/* local functions */
+int contline_next P((void));
+void addline P((line_t **lp, char *str));
+void usage P((void));
+int main P((int argc, char **argv));
+
+void copy_template_file P((char *lbl_templ));
+void do_postscript_output P((void));
+void handle_start P((void));
+void handle_finish P((void));
+void handle_note P((void));
+void handle_summary P((void));
+void handle_stats P((void));
+void handle_error P((void));
+void handle_disk P((void));
+repdata_t *handle_success P((void));
+void handle_strange P((void));
+void handle_failed P((void));
+void generate_missing P((void));
+void output_tapeinfo P((void));
+void output_lines P((line_t *lp, FILE *f));
+void output_stats P((void));
+void output_summary P((void));
+void sort_disks P((void));
+int sort_by_time P((disk_t *a, disk_t *b));
+int sort_by_name P((disk_t *a, disk_t *b));
+void bogus_line P((void));
+char *nicedate P((int datestamp));
+static char *prefix P((char *host, char *disk, int level));
+repdata_t *find_repdata P((disk_t *dp, char *datestamp, int level));
+
+
+static int ColWidth(int From, int To) {
+    int i, Width= 0;
+    for (i=From; i<=To && ColumnData[i].Name != NULL; i++) {
+       Width+= ColumnData[i].PrefixSpace + ColumnData[i].Width;
+    }
+    return Width;
+}
+
+static char *Rule(int From, int To) {
+    int i, ThisLeng;
+    int Leng= ColWidth(0, ColumnDataCount());
+    char *RuleSpace= alloc(Leng+1);
+    ThisLeng= ColWidth(From, To);
+    for (i=0;i<ColumnData[From].PrefixSpace; i++)
+       RuleSpace[i]= ' ';
+    for (; i<ThisLeng; i++)
+       RuleSpace[i]= '-';
+    RuleSpace[ThisLeng]= '\0';
+    return RuleSpace;
+}
+
+static char *TextRule(int From, int To, char *s) {
+    ColumnInfo *cd= &ColumnData[From];
+    int leng, nbrules, i, txtlength;
+    int RuleSpaceSize= ColWidth(0, ColumnDataCount());
+    char *RuleSpace= alloc(RuleSpaceSize), *tmp;
+
+    leng= strlen(s);
+    if(leng >= (RuleSpaceSize - cd->PrefixSpace))
+       leng = RuleSpaceSize - cd->PrefixSpace - 1;
+    ap_snprintf(RuleSpace, RuleSpaceSize, "%*s%*.*s ", cd->PrefixSpace, "", 
+               leng, leng, s);
+    txtlength = cd->PrefixSpace + leng + 1;
+    nbrules = ColWidth(From,To) - txtlength;
+    for(tmp=RuleSpace + txtlength, i=nbrules ; i>0; tmp++,i--)
+       *tmp='-';
+    *tmp = '\0';
+    return RuleSpace;
+}
+
+char *sDivZero(float a, float b, int cn) {
+    ColumnInfo *cd= &ColumnData[cn];
+    static char PrtBuf[256];
+    if (b == 0.0)
+       ap_snprintf(PrtBuf, sizeof(PrtBuf),
+         "%*s", cd->Width, "-- ");
+    else
+       ap_snprintf(PrtBuf, sizeof(PrtBuf),
+         cd->Format, cd->Width, cd->Precision, a/b);
+    return PrtBuf;
+}
+
+
+
+int contline_next()
+{
+    int ch;
+
+    ch = getc(logfile);
+    ungetc(ch, logfile);
+
+    return ch == ' ';
+}
+
+void addline(lp, str)
+line_t **lp;
+char *str;
+{
+    line_t *new, *p, *q;
+
+    /* allocate new line node */
+    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;
+}
+
+void usage()
+{
+    error("Usage: amreport conf [-f output-file] [-l logfile] [-p postscript-file]");
+}
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+    char *conffile;
+    char *conf_diskfile;
+    char *conf_tapelist;
+    char *conf_infofile;
+    char *logfname, *psfname, *outfname, *subj_str = NULL;
+    tapetype_t *tp;
+    int fd, opt;
+    unsigned long malloc_hist_1, malloc_size_1;
+    unsigned long malloc_hist_2, malloc_size_2;
+    char *mail_cmd = NULL, *printer_cmd = NULL;
+    extern int optind;
+    char my_cwd[STR_SIZE];
+    char *ColumnSpec = "";
+    char *errstr = NULL;
+    int cn;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("amreport");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    /* Process options */
+    
+    erroutput_type = ERR_INTERACTIVE;
+    outfname = NULL;
+    psfname = NULL;
+    logfname = NULL;
+
+    if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+       error("cannot determine current working directory");
+    }
+
+    if (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] == '-') {
+           usage();
+           return 1;
+       }
+       config_name = stralloc(argv[1]);
+       config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+       --argc; ++argv;
+       while((opt = getopt(argc, argv, "f:l:p:")) != EOF) {
+           switch(opt) {
+            case 'f':
+               if (outfname != NULL) {
+                   error("you may specify at most one -f");
+               }
+               if (*optarg == '/') {
+                    outfname = stralloc(optarg);
+               } else {
+                    outfname = vstralloc(my_cwd, "/", optarg, NULL);
+               }
+                break;
+            case 'l':
+               if (logfname != NULL) {
+                   error("you may specify at most one -l");
+               }
+               if (*optarg == '/') {
+                   logfname = stralloc(optarg);
+               } else {
+                    logfname = vstralloc(my_cwd, "/", optarg, NULL);
+               }
+                break;
+            case 'p':
+               if (psfname != NULL) {
+                   error("you may specify at most one -p");
+               }
+               if (*optarg == '/') {
+                    psfname = stralloc(optarg);
+               } else {
+                    psfname = vstralloc(my_cwd, "/", optarg, NULL);
+               }
+                break;
+            case '?':
+            default:
+               usage();
+               return 1;
+           }
+       }
+
+       argc -= optind;
+       argv += optind;
+
+       if (argc > 1) {
+           usage();
+           return 1;
+       }
+    }
+
+#if !defined MAILER
+    if(!outfname) {
+       printf("You must run amreport with '-f <output file>' because configure\n");
+       printf("didn't find a mailer.\n");
+       exit (1);
+    }
+#endif
+
+    safe_cd();
+
+    /* read configuration files */
+
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if(read_conffile(conffile)) {
+        error("errors processing config file \"%s\"", conffile);
+    }
+    amfree(conffile);
+    conf_diskfile = getconf_str(CNF_DISKFILE);
+    if (*conf_diskfile == '/') {
+       conf_diskfile = stralloc(conf_diskfile);
+    } else {
+       conf_diskfile = stralloc2(config_dir, conf_diskfile);
+    }
+    if((diskq = read_diskfile(conf_diskfile)) == NULL) {
+       error("could not load disklist \"%s\"", conf_diskfile);
+    }
+    amfree(conf_diskfile);
+    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);
+    }
+    amfree(conf_tapelist);
+    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)) {
+       error("could not open info db \"%s\"", conf_infofile);
+    }
+    amfree(conf_infofile);
+
+    today_datestamp = construct_datestamp(NULL);
+
+    ColumnSpec = getconf_str(CNF_COLUMNSPEC);
+    if(SetColumDataFromString(ColumnData, ColumnSpec, &errstr) < 0) {
+       curlog = L_ERROR;
+       curprog = P_REPORTER;
+       curstr = errstr;
+       handle_error();
+        amfree(errstr);
+       curstr = NULL;
+       ColumnSpec = "";                /* use the default */
+       if(SetColumDataFromString(ColumnData, ColumnSpec, &errstr) < 0) {
+           curlog = L_ERROR;
+           curprog = P_REPORTER;
+           curstr = errstr;
+           handle_error();
+            amfree(errstr);
+           curstr = NULL;
+       }
+    }
+    for (cn = 0; ColumnData[cn].Name != NULL; cn++) {
+       if (ColumnData[cn].MaxWidth) {
+           MaxWidthsRequested = 1;
+           break;
+       }
+    }
+
+    if(!logfname) {
+       char *conf_logdir;
+
+       conf_logdir = getconf_str(CNF_LOGDIR);
+       if (*conf_logdir == '/') {
+           conf_logdir = stralloc(conf_logdir);
+       } else {
+           conf_logdir = stralloc2(config_dir, conf_logdir);
+       }
+       logfname = vstralloc(conf_logdir, "/", "log", NULL);
+       amfree(conf_logdir);
+    }
+
+    if((logfile = fopen(logfname, "r")) == NULL) {
+       curlog = L_ERROR;
+       curprog = P_REPORTER;
+       curstr = vstralloc("could not open log ",
+                          logfname,
+                          ": ",
+                          strerror(errno),
+                          NULL);
+       handle_error();
+       amfree(curstr);
+    }
+
+    while(logfile && get_logline(logfile)) {
+       switch(curlog) {
+       case L_START:   handle_start(); break;
+       case L_FINISH:  handle_finish(); break;
+
+       case L_INFO:    handle_note(); break;
+       case L_WARNING: handle_note(); break;
+
+       case L_SUMMARY: handle_summary(); break;
+       case L_STATS:   handle_stats(); break;
+
+       case L_ERROR:   handle_error(); break;
+       case L_FATAL:   handle_error(); break;
+
+       case L_DISK:    handle_disk(); break;
+
+       case L_SUCCESS: handle_success(); break;
+       case L_STRANGE: handle_strange(); break;
+       case L_FAIL:    handle_failed(); break;
+
+       default:
+           curlog = L_ERROR;
+           curprog = P_REPORTER;
+           curstr = stralloc2("unexpected log line: ", curstr);
+           handle_error();
+           amfree(curstr);
+       }
+    }
+    afclose(logfile);
+    close_infofile();
+    if(!amflush_run)
+       generate_missing();
+
+    subj_str = vstralloc(getconf_str(CNF_ORG),
+                        " ", amflush_run ? "AMFLUSH" : "AMANDA",
+                        " ", "MAIL REPORT FOR",
+                        " ", nicedate(run_datestamp ? atoi(run_datestamp) : 0),
+                        NULL);
+       
+    /* lookup the tapetype and printer type from the amanda.conf file. */
+    tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
+    printer = getconf_str(CNF_PRINTER);
+
+    /* ignore SIGPIPE so if a child process dies we do not also go away */
+    signal(SIGPIPE, SIG_IGN);
+
+    /* open pipe to mailer */
+
+    if(outfname) {
+       /* output to a file */
+       if((mailf = fopen(outfname,"w")) == NULL) {
+           error("could not open output file: %s %s", outfname, strerror(errno));
+       }
+       fprintf(mailf, "To: %s\n", getconf_str(CNF_MAILTO));
+       fprintf(mailf, "Subject: %s\n\n", subj_str);
+
+    } else {
+#ifdef MAILER
+       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));
+#endif
+    }
+
+    /* open pipe to print spooler if necessary) */
+
+    if(psfname) {
+       /* 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 ((postscript = fopen(psfname, "w")) == NULL) {
+               curlog = L_ERROR;
+               curprog = P_REPORTER;
+               curstr = vstralloc("could not open ",
+                                  psfname,
+                                  ": ",
+                                  strerror(errno),
+                                  NULL);
+               handle_error();
+               amfree(curstr);
+           }
+       }
+    } else {
+#ifdef LPRCMD
+       if (strcmp(printer, "") != 0)   /* alternate printer is defined */
+           /* print to the specified printer */
+#ifdef LPRFLAG
+           printer_cmd = vstralloc(LPRCMD, " ", LPRFLAG, printer, NULL);
+#else
+           printer_cmd = vstralloc(LPRCMD, NULL);
+#endif
+       else
+           /* print to the default printer */
+           printer_cmd = vstralloc(LPRCMD, NULL);
+#endif
+
+       if ((strcmp(tp->lbl_templ, "")) != 0) {
+#ifdef LPRCMD
+           if ((postscript = popen(printer_cmd, "w")) == NULL) {
+               curlog = L_ERROR;
+               curprog = P_REPORTER;
+               curstr = vstralloc("could not open pipe to ",
+                                  printer_cmd,
+                                  ": ",
+                                  strerror(errno),
+                                  NULL);
+               handle_error();
+               amfree(curstr);
+           }
+#else
+           curlog = L_ERROR;
+           curprog = P_REPORTER;
+           curstr = stralloc("no printer command defined");
+           handle_error();
+           amfree(curstr);
+#endif
+       }
+    }
+
+    amfree(subj_str);
+
+
+    if(!got_finish) fputs("*** THE DUMPS DID NOT FINISH PROPERLY!\n\n", mailf);
+
+    output_tapeinfo();
+
+    if(errsum) {
+       fprintf(mailf,"\nFAILURE AND STRANGE DUMP SUMMARY:\n");
+       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());
+
+    if (postscript) {
+       do_postscript_output();
+    }
+
+
+    /* close postscript file */
+    if (psfname && postscript) {
+       /* it may be that postscript is NOT opened */
+       afclose(postscript);
+    }
+    else {
+       if (postscript != NULL && pclose(postscript) != 0)
+           error("printer command failed: %s", printer_cmd);
+       postscript = NULL;
+    }
+
+    /* close output file */
+    if(outfname) {
+        afclose(mailf);
+    }
+    else {
+        if(pclose(mailf) != 0)
+            error("mail command failed: %s", mail_cmd);
+        mailf = NULL;
+    }
+
+    amfree(run_datestamp);
+    amfree(tape_labels);
+    amfree(config_dir);
+    amfree(config_name);
+    amfree(printer_cmd);
+    amfree(mail_cmd);
+    amfree(logfname);
+
+    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 0;
+}
+
+/* ----- */
+
+#define mb(f)  ((f)/1024.0)            /* kbytes -> mbytes */
+#define pct(f) ((f)*100.0)             /* percent */
+#define hrmn(f) ((int)(f)+30)/3600, (((int)(f)+30)%3600)/60
+#define mnsc(f) ((int)(f+0.5))/60, ((int)(f+0.5)) % 60
+
+#define divzero(fp,a,b)                            \
+    do {                                           \
+       double q = (b);                     \
+       if (q == 0.0)                       \
+           fprintf((fp),"  -- ");          \
+       else if ((q = (a)/q) >= 999.95)     \
+           fprintf((fp), "###.#");         \
+       else                                \
+           fprintf((fp), "%5.1f",q);       \
+    } while(0)
+#define divzero_wide(fp,a,b)               \
+    do {                                           \
+       double q = (b);                     \
+       if (q == 0.0)                       \
+           fprintf((fp),"    -- ");        \
+       else if ((q = (a)/q) >= 99999.95)   \
+           fprintf((fp), "#####.#");       \
+       else                                \
+           fprintf((fp), "%7.1f",q);       \
+    } while(0)
+
+void output_stats()
+{
+    double idle_time;
+    tapetype_t *tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
+    int tapesize, marksize, lv, first;
+
+    tapesize = tp->length;
+    marksize = tp->filemark;
+
+    stats[2].dumpdisks   = stats[0].dumpdisks   + stats[1].dumpdisks;
+    stats[2].tapedisks   = stats[0].tapedisks   + stats[1].tapedisks;
+    stats[2].outsize     = stats[0].outsize     + stats[1].outsize;
+    stats[2].origsize    = stats[0].origsize    + stats[1].origsize;
+    stats[2].tapesize    = stats[0].tapesize    + stats[1].tapesize;
+    stats[2].coutsize    = stats[0].coutsize    + stats[1].coutsize;
+    stats[2].corigsize   = stats[0].corigsize   + stats[1].corigsize;
+    stats[2].taper_time  = stats[0].taper_time  + stats[1].taper_time;
+    stats[2].dumper_time = stats[0].dumper_time + stats[1].dumper_time;
+
+    if(!got_finish)    /* no driver finish line, estimate total run time */
+       total_time = stats[2].taper_time + startup_time;
+
+    idle_time = (total_time - startup_time) - stats[2].taper_time;
+    if(idle_time < 0) idle_time = 0.0;
+
+    fprintf(mailf,"STATISTICS:\n");
+    fprintf(mailf,
+           "                          Total       Full      Daily\n");
+    fprintf(mailf,
+           "                        --------   --------   --------\n");
+
+    fprintf(mailf,
+           "Estimate Time (hrs:min)   %2d:%02d\n", hrmn(startup_time));
+
+    fprintf(mailf,
+           "Run Time (hrs:min)        %2d:%02d\n", hrmn(total_time));
+
+    fprintf(mailf,
+           "Dump Time (hrs:min)       %2d:%02d      %2d:%02d      %2d:%02d\n",
+           hrmn(stats[2].dumper_time), hrmn(stats[0].dumper_time),
+           hrmn(stats[1].dumper_time));
+
+    fprintf(mailf,
+           "Output Size (meg)      %8.1f   %8.1f   %8.1f\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",
+           mb(stats[2].origsize), mb(stats[0].origsize),
+           mb(stats[1].origsize));
+
+    fprintf(mailf, "Avg Compressed Size (%%)   ");
+    divzero(mailf, pct(stats[2].coutsize),stats[2].corigsize);
+    fputs("      ", mailf);
+    divzero(mailf, pct(stats[0].coutsize),stats[0].corigsize);
+    fputs("      ", mailf);
+    divzero(mailf, pct(stats[1].coutsize),stats[1].corigsize);
+
+    if(stats[1].dumpdisks > 0) fputs("   (level:#disks ...)", mailf);
+    putc('\n', mailf);
+
+    fprintf(mailf,
+           "Filesystems Dumped         %4d       %4d       %4d",
+           stats[2].dumpdisks, stats[0].dumpdisks, stats[1].dumpdisks);
+
+    if(stats[1].dumpdisks > 0) {
+       first = 1;
+       for(lv = 1; lv < 10; lv++) if(dumpdisks[lv]) {
+           fputs(first?"   (":" ", mailf);
+           first = 0;
+           fprintf(mailf, "%d:%d", lv, dumpdisks[lv]);
+       }
+       putc(')', mailf);
+    }
+    putc('\n', mailf);
+
+    fprintf(mailf, "Avg Dump Rate (k/s)     ");
+    divzero_wide(mailf, stats[2].outsize,stats[2].dumper_time);
+    fputs("    ", mailf);
+    divzero_wide(mailf, stats[0].outsize,stats[0].dumper_time);
+    fputs("    ", mailf);
+    divzero_wide(mailf, stats[1].outsize,stats[1].dumper_time);
+    putc('\n', mailf);
+
+    putc('\n', mailf);
+    fprintf(mailf,
+           "Tape Time (hrs:min)       %2d:%02d      %2d:%02d      %2d:%02d\n",
+           hrmn(stats[2].taper_time), hrmn(stats[0].taper_time),
+           hrmn(stats[1].taper_time));
+
+    fprintf(mailf,
+           "Tape Size (meg)        %8.1f   %8.1f   %8.1f\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),tapesize);
+    fputs("      ", mailf);
+    divzero(mailf, pct(stats[0].tapesize+marksize*stats[0].tapedisks),tapesize);
+    fputs("      ", mailf);
+    divzero(mailf, pct(stats[1].tapesize+marksize*stats[1].tapedisks),tapesize);
+
+    if(stats[1].tapedisks > 0) fputs("   (level:#disks ...)", mailf);
+    putc('\n', mailf);
+
+    fprintf(mailf,
+           "Filesystems Taped          %4d       %4d       %4d",
+           stats[2].tapedisks, stats[0].tapedisks, stats[1].tapedisks);
+
+    if(stats[1].tapedisks > 0) {
+       first = 1;
+       for(lv = 1; lv < 10; lv++) if(tapedisks[lv]) {
+           fputs(first?"   (":" ", mailf);
+           first = 0;
+           fprintf(mailf, "%d:%d", lv, tapedisks[lv]);
+       }
+       putc(')', mailf);
+    }
+    putc('\n', mailf);
+
+    fprintf(mailf, "Avg Tp Write Rate (k/s) ");
+    divzero_wide(mailf, stats[2].tapesize,stats[2].taper_time);
+    fputs("    ", mailf);
+    divzero_wide(mailf, stats[0].tapesize,stats[0].taper_time);
+    fputs("    ", mailf);
+    divzero_wide(mailf, stats[1].tapesize,stats[1].taper_time);
+    putc('\n', mailf);
+
+    if(stats_by_tape) {
+       int label_length = strlen(stats_by_tape->label) + 5;
+       fprintf(mailf,"\nUSAGE BY TAPE:\n");
+       fprintf(mailf,"  %-*s  Time      Size      %%    Nb\n",
+               label_length, "Label");
+       for(current_tape = stats_by_tape; current_tape != NULL;
+           current_tape = current_tape->next) {
+           fprintf(mailf, "  %-*s", label_length, current_tape->label);
+           fprintf(mailf, " %2d:%02d", hrmn(current_tape->taper_time));
+           fprintf(mailf, " %9.1f  ", mb(current_tape->coutsize));
+           divzero(mailf, pct(current_tape->coutsize + 
+                              marksize * current_tape->tapedisks),
+                          tapesize);
+           fprintf(mailf, "  %4d\n", current_tape->tapedisks);
+       }
+    }
+
+}
+
+/* ----- */
+
+void output_tapeinfo()
+{
+    tape_t *tp, *lasttp;
+    int run_tapes;
+    int skip = 0;
+
+    if (last_run_tapes > 0) {
+       if(amflush_run)
+           fprintf(mailf, "The dumps were flushed to tape%s %s.\n",
+                   last_run_tapes == 1 ? "" : "s",
+                   tape_labels ? tape_labels : "");
+       else
+           fprintf(mailf, "These dumps were to tape%s %s.\n",
+                   last_run_tapes == 1 ? "" : "s",
+                   tape_labels ? tape_labels : "");
+    }
+
+    if(degraded_mode) {
+       fprintf(mailf,
+               "*** A TAPE ERROR OCCURRED: %s.\n", tapestart_error);
+       fputs("Some dumps may have been left in the holding disk.\n", mailf);
+       fprintf(mailf,
+               "Run amflush%s to flush them to tape.\n",
+               amflush_run ? " again" : "");
+    }
+
+    tp = lookup_last_reusable_tape(skip);
+
+    run_tapes = getconf_int(CNF_RUNTAPES);
+
+    if (run_tapes <= 1)
+       fputs("The next tape Amanda expects to use is: ", mailf);
+    else
+       fprintf(mailf, "The next %d tapes Amanda expects to used are: ",
+               run_tapes);
+    
+    while(run_tapes > 0) {
+       if(tp != NULL)
+           fprintf(mailf, "%s", tp->label);
+       else
+           fputs("a new tape", mailf);
+
+       if(run_tapes > 1) fputs(", ", mailf);
+
+       run_tapes -= 1;
+       skip++;
+       tp = lookup_last_reusable_tape(skip);
+    }
+    fputs(".\n", mailf);
+
+    lasttp = lookup_tapepos(lookup_nb_tape());
+    run_tapes = getconf_int(CNF_RUNTAPES);
+    if(lasttp && run_tapes > 0 && lasttp->datestamp == 0) {
+       int c = 0;
+       while(lasttp && run_tapes > 0 && lasttp->datestamp == 0) {
+           c++;
+           lasttp = lasttp->prev;
+           run_tapes--;
+       }
+       lasttp = lookup_tapepos(lookup_nb_tape());
+       if(c == 1) {
+           fprintf(mailf, "The next new tape already labelled is: %s.\n",
+                   lasttp->label);
+       }
+       else {
+           fprintf(mailf, "The next %d new tapes already labelled are: %s", c,
+                   lasttp->label);
+           lasttp = lasttp->prev;
+           c--;
+           while(lasttp && c > 0 && lasttp->datestamp == 0) {
+               fprintf(mailf, ", %s", lasttp->label);
+               lasttp = lasttp->prev;
+               c--;
+           }
+           fprintf(mailf, ".\n");
+       }
+    }
+}
+
+/* ----- */
+
+void output_lines(lp, f)
+line_t *lp;
+FILE *f;
+{
+    line_t *next;
+
+    while(lp) {
+       fputs(lp->str, f);
+       amfree(lp->str);
+       fputc('\n', f);
+       next = lp->next;
+       amfree(lp);
+       lp = next;
+    }
+}
+
+/* ----- */
+
+int sort_by_time(a, b)
+disk_t *a, *b;
+{
+    return data(b)->dumper.sec - data(a)->dumper.sec;
+}
+
+int sort_by_name(a, b)
+disk_t *a, *b;
+{
+    int rc;
+
+    rc = strcmp(a->host->hostname, b->host->hostname);
+    if(rc == 0) rc = strcmp(a->name, b->name);
+    return rc;
+}
+
+void sort_disks()
+{
+    disk_t *dp;
+
+    sortq.head = sortq.tail = NULL;
+    while(!empty(*diskq)) {
+       dp = dequeue_disk(diskq);
+       if(data(dp) == NULL) { /* create one */
+           find_repdata(dp, run_datestamp, 0);
+       }
+       insert_disk(&sortq, dp, sort_by_name);
+    }
+}
+
+void CheckStringMax(ColumnInfo *cd, char *s) {
+    if (cd->MaxWidth) {
+       int l= strlen(s);
+       if (cd->Width < l)
+           cd->Width= l;
+    }
+}
+
+void CheckIntMax(ColumnInfo *cd, int n) {
+    if (cd->MaxWidth) {
+       char testBuf[200];
+       int l;
+       ap_snprintf(testBuf, sizeof(testBuf),
+         cd->Format, cd->Width, cd->Precision, n);
+       l= strlen(testBuf);
+       if (cd->Width < l)
+           cd->Width= l;
+    }
+}
+
+void CheckFloatMax(ColumnInfo *cd, double d) {
+    if (cd->MaxWidth) {
+       char testBuf[200];
+       int l;
+       ap_snprintf(testBuf, sizeof(testBuf),
+         cd->Format, cd->Width, cd->Precision, d);
+       l= strlen(testBuf);
+       if (cd->Width < l)
+           cd->Width= l;
+    }
+}
+
+static int HostName;
+static int Disk;
+static int Level;
+static int OrigKB;
+static int OutKB;
+static int Compress;
+static int DumpTime;
+static int DumpRate;
+static int TapeTime;
+static int TapeRate;
+
+void CalcMaxWidth() {
+    /* we have to look for columspec's, that require the recalculation.
+     * we do here the same loops over the sortq as is done in
+     * output_summary. So, if anything is changed there, we have to
+     * change this here also.
+     *                                                 ElB, 1999-02-24.
+     */
+    disk_t *dp;
+    float 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);
+           CheckStringMax(&ColumnData[Disk], dp->name);
+           if (repdata->dumper.result == L_BOGUS && 
+               repdata->taper.result == L_BOGUS)
+               continue;
+           CheckIntMax(&ColumnData[Level], repdata->level);
+           if(repdata->dumper.result == L_SUCCESS) {
+               CheckFloatMax(&ColumnData[OrigKB], repdata->dumper.origsize);
+               CheckFloatMax(&ColumnData[OutKB], repdata->dumper.outsize);
+               if(dp->compress == COMP_NONE)
+                   f = 0.0;
+               else 
+                   f = repdata->dumper.origsize;
+               CheckStringMax(&ColumnData[Disk], 
+                       sDivZero(pct(repdata->dumper.outsize), f, Compress));
+
+               if(!amflush_run)
+                   ap_snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                               "%3d:%02d", mnsc(repdata->dumper.sec));
+               else
+                   ap_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");
+               continue;
+           }
+           if(repdata->taper.result == L_SUCCESS)
+               ap_snprintf(TimeRateBuffer, sizeof(TimeRateBuffer), 
+                 "%3d:%02d", mnsc(repdata->taper.sec));
+           else
+               ap_snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                 "N/A ");
+           CheckStringMax(cd, TimeRateBuffer);
+
+           cd= &ColumnData[TapeRate];
+           if(repdata->taper.result == L_SUCCESS)
+               CheckFloatMax(cd, repdata->taper.kps);
+           else
+               CheckStringMax(cd, "N/A ");
+       }
+      }
+    }
+}
+
+void output_summary()
+{
+    disk_t *dp;
+    repdata_t *repdata;
+    char *ds="DUMPER STATS";
+    char *ts=" TAPER STATS";
+    char *tmp;
+
+    int i, h, w1, wDump, wTape;
+    float outsize, origsize;
+    float f;
+
+    HostName = StringToColumn("HostName");
+    Disk = StringToColumn("Disk");
+    Level = StringToColumn("Level");
+    OrigKB = StringToColumn("OrigKB");
+    OutKB = StringToColumn("OutKB");
+    Compress = StringToColumn("Compress");
+    DumpTime = StringToColumn("DumpTime");
+    DumpRate = StringToColumn("DumpRate");
+    TapeTime = StringToColumn("TapeTime");
+    TapeRate = StringToColumn("TapeRate");
+
+    /* at first determine if we have to recalculate our widths */
+    if (MaxWidthsRequested)
+       CalcMaxWidth();
+
+    /* title for Dumper-Stats */
+    w1= ColWidth(HostName, Level);
+    wDump= ColWidth(OrigKB, DumpRate);
+    wTape= ColWidth(TapeTime, TapeRate);
+
+    /* print centered top titles */
+    h= strlen(ds);
+    if (h > wDump) {
+       h= 0;
+    } else {
+       h= (wDump-h)/2;
+    }
+    fprintf(mailf, "%*s", w1+h, "");
+    fprintf(mailf, "%-*s", wDump-h, ds);
+    h= strlen(ts);
+    if (h > wTape) {
+       h= 0;
+    } else {
+       h= (wTape-h)/2;
+    }
+    fprintf(mailf, "%*s", h, "");
+    fprintf(mailf, "%-*s", wTape-h, ts);
+    fputc('\n', mailf);
+
+    /* print the titles */
+    for (i=0; ColumnData[i].Name != NULL; i++) {
+       char *fmt;
+       ColumnInfo *cd= &ColumnData[i];
+       fprintf(mailf, "%*s", cd->PrefixSpace, "");
+       if (cd->Format[1] == '-')
+           fmt= "%-*s";
+       else
+           fmt= "%*s";
+       fprintf(mailf, fmt, cd->Width, cd->Title);
+    }
+    fputc('\n', mailf);
+
+    /* print the rules */
+    fputs(tmp=Rule(HostName, Level), mailf); amfree(tmp);
+    fputs(tmp=Rule(OrigKB, DumpRate), mailf); amfree(tmp);
+    fputs(tmp=Rule(TapeTime, TapeRate), mailf); amfree(tmp);
+    fputc('\n', mailf);
+
+    for(dp = sortq.head; dp != NULL; dp = dp->next) {
+      if(dp->todo) {
+       ColumnInfo *cd;
+       char TimeRateBuffer[40];
+       for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
+           int devlen;
+
+           cd= &ColumnData[HostName];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           fprintf(mailf, cd->Format, cd->Width, cd->Width, dp->host->hostname);
+
+           cd= &ColumnData[Disk];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           devlen= strlen(dp->name);
+           if (devlen > cd->Width) {
+               fputc('-', mailf); 
+               fprintf(mailf, cd->Format, cd->Width-1, cd->Precision-1,
+                 dp->name+devlen - (cd->Width-1) );
+           }
+           else
+               fprintf(mailf, cd->Format, cd->Width, cd->Width, dp->name);
+
+           cd= &ColumnData[Level];
+           if (repdata->dumper.result == L_BOGUS &&
+               repdata->taper.result  == L_BOGUS) {
+             if(amflush_run){
+               fprintf(mailf, "%*s%s\n", cd->PrefixSpace+cd->Width, "",
+                       tmp=TextRule(OrigKB, TapeRate, "NO FILE TO FLUSH"));
+             } else {
+               fprintf(mailf, "%*s%s\n", cd->PrefixSpace+cd->Width, "",
+                       tmp=TextRule(OrigKB, TapeRate, "MISSING"));
+             }
+             amfree(tmp);
+             continue;
+           }
+           
+           cd= &ColumnData[Level];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           fprintf(mailf, cd->Format, cd->Width, cd->Precision,repdata->level);
+
+           if (repdata->dumper.result == L_SKIPPED) {
+               fprintf(mailf, "%s\n",
+                       tmp=TextRule(OrigKB, TapeRate, "SKIPPED"));
+               amfree(tmp);
+               continue;
+           }
+           if (repdata->dumper.result == L_FAIL) {
+               fprintf(mailf, "%s\n",
+                       tmp=TextRule(OrigKB, TapeRate, "FAILED"));
+               amfree(tmp);
+               continue;
+           }
+
+           if(repdata->dumper.result == L_SUCCESS)
+               origsize = repdata->dumper.origsize;
+           else
+               origsize = repdata->taper.origsize;
+
+           if(repdata->taper.result == L_SUCCESS) 
+               outsize  = repdata->taper.outsize;
+           else
+               outsize  = repdata->dumper.outsize;
+
+           cd= &ColumnData[OrigKB];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           if(origsize != 0.0)
+               fprintf(mailf, cd->Format, cd->Width, cd->Precision, origsize);
+           else
+               fprintf(mailf, "%*.*s", cd->Width, cd->Width, "N/A");
+
+           cd= &ColumnData[OutKB];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+
+           fprintf(mailf, cd->Format, cd->Width, cd->Precision, outsize);
+               
+           cd= &ColumnData[Compress];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+
+           if(dp->compress == COMP_NONE)
+               f = 0.0;
+           else if(origsize < 1.0)
+               f = 0.0;
+           else
+               f = origsize;
+
+           fputs(sDivZero(pct(outsize), f, Compress), mailf);
+
+           cd= &ColumnData[DumpTime];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           if(repdata->dumper.result == L_SUCCESS)
+               ap_snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                 "%3d:%02d", mnsc(repdata->dumper.sec));
+           else
+               ap_snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                 "N/A ");
+           fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer);
+
+           cd= &ColumnData[DumpRate];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           if(repdata->dumper.result == L_SUCCESS)
+               fprintf(mailf, cd->Format, cd->Width, cd->Precision, repdata->dumper.kps);
+           else
+               fprintf(mailf, "%*s", cd->Width, "N/A ");
+
+           cd= &ColumnData[TapeTime];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           if(repdata->taper.result == L_FAIL) {
+               fprintf(mailf, "%s\n",
+                       tmp=TextRule(TapeTime, TapeRate, "FAILED "));
+               amfree(tmp);
+               continue;
+           }
+
+           if(repdata->taper.result == L_SUCCESS)
+               ap_snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                 "%3d:%02d", mnsc(repdata->taper.sec));
+           else
+               ap_snprintf(TimeRateBuffer, sizeof(TimeRateBuffer),
+                 "N/A ");
+           fprintf(mailf, cd->Format, cd->Width, cd->Width, TimeRateBuffer);
+
+           cd= &ColumnData[TapeRate];
+           fprintf(mailf, "%*s", cd->PrefixSpace, "");
+           if(repdata->taper.result == L_SUCCESS)
+               fprintf(mailf, cd->Format, cd->Width, cd->Precision, repdata->taper.kps);
+           else
+               fprintf(mailf, "%*s", cd->Width, "N/A ");
+           fputc('\n', mailf);
+       }
+      }
+    }
+}
+
+void bogus_line()
+{
+    printf("line %d of log is bogus\n", curlinenum);
+}
+
+
+char *nicedate(datestamp)
+int datestamp;
+/*
+ * Formats an integer of the form YYYYMMDD 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 nice[64];
+    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;
+
+    ap_snprintf(nice, sizeof(nice), "%s %d, %d", months[month], day, year);
+
+    return nice;
+}
+
+void handle_start()
+{
+    static int started = 0;
+    char *label;
+    char *s, *fp;
+    int ch;
+
+    switch(curprog) {
+    case P_TAPER:
+       s = curstr;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+#define sc "datestamp"
+       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           bogus_line();
+           return;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           bogus_line();
+           return;
+       }
+       fp = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       run_datestamp = newstralloc(run_datestamp, fp);
+       s[-1] = ch;
+
+       skip_whitespace(s, ch);
+#define sc "label"
+       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           bogus_line();
+           return;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           bogus_line();
+           return;
+       }
+       fp = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+
+       label = stralloc(fp);
+       s[-1] = ch;
+
+       if(tape_labels) {
+           fp = vstralloc(tape_labels, ", ", label, NULL);
+           amfree(tape_labels);
+           tape_labels = fp;
+       } else {
+           tape_labels = stralloc(label);
+       }
+
+       last_run_tapes++;
+
+       if(stats_by_tape == NULL) {
+           stats_by_tape = current_tape = (taper_t *)alloc(sizeof(taper_t));
+       }
+       else {
+           current_tape->next = (taper_t *)alloc(sizeof(taper_t));
+           current_tape = current_tape->next;
+       }
+       current_tape->label = label;
+       current_tape->taper_time = 0.0;
+       current_tape->coutsize = 0.0;
+       current_tape->corigsize = 0.0;
+       current_tape->tapedisks = 0;
+       current_tape->next = NULL;
+       tapefcount = 0;
+
+       return;
+    case P_PLANNER:
+       normal_run = 1;
+       break;
+    case P_DRIVER:
+       break;
+    case P_AMFLUSH:
+       amflush_run = 1;
+       break;
+    default:
+       ;
+    }
+
+    if(!started) {
+       s = curstr;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+#define sc "date"
+       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           return;                             /* ignore bogus line */
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           bogus_line();
+           return;
+       }
+       fp = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       run_datestamp = newstralloc(run_datestamp, fp);
+       s[-1] = ch;
+
+       started = 1;
+    }
+    if(amflush_run && normal_run) {
+       amflush_run = 0;
+       addline(&notes,
+     "  reporter: both amflush and planner output in log, ignoring amflush.");
+    }
+}
+
+
+void handle_finish()
+{
+    char *s;
+    int ch;
+
+    if(curprog == P_DRIVER || curprog == P_AMFLUSH) {
+       s = curstr;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+#define sc "date"
+       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           bogus_line();
+           return;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           bogus_line();
+           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) {
+           bogus_line();
+           return;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           bogus_line();
+           return;
+       }
+       if(sscanf(s - 1, "%f", &total_time) != 1) {
+           bogus_line();
+           return;
+       }
+
+       got_finish = 1;
+    }
+}
+
+void handle_stats()
+{
+    char *s;
+    int ch;
+
+    if(curprog == P_DRIVER) {
+       s = curstr;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+#define sc "startup time"
+       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           bogus_line();
+           return;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+
+       skip_whitespace(s, ch);
+       if(ch == '\0') {
+           bogus_line();
+           return;
+       }
+       if(sscanf(s - 1, "%f", &startup_time) != 1) {
+           bogus_line();
+           return;
+       }
+    }
+}
+
+
+void handle_note()
+{
+    char *str = NULL;
+
+    str = vstralloc("  ", program_str[curprog], ": ", curstr, NULL);
+    addline(&notes, str);
+    amfree(str);
+}
+
+
+/* ----- */
+
+void handle_error()
+{
+    char *s = NULL, *nl;
+    int ch;
+
+    if(curlog == L_ERROR && curprog == P_TAPER) {
+       s = curstr;
+       ch = *s++;
+
+       skip_whitespace(s, ch);
+#define sc "no-tape"
+       if(ch == '\0' || strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+           bogus_line();
+           return;
+       }
+       s += sizeof(sc)-1;
+       ch = s[-1];
+#undef sc
+
+       skip_whitespace(s, ch);
+       if(ch != '\0') {
+           if((nl = strchr(s - 1, '\n')) != NULL) {
+               *nl = '\0';
+           }
+           tapestart_error = newstralloc(tapestart_error, s - 1);
+           if(nl) *nl = '\n';
+           degraded_mode = 1;
+           return;
+       }
+       /* else some other tape error, handle like other errors */
+    }
+    s = vstralloc("  ", program_str[curprog], ": ",
+                 logtype_str[curlog], " ", curstr, NULL);
+    addline(&errsum, s);
+    amfree(s);
+}
+
+/* ----- */
+
+void handle_summary()
+{
+    bogus_line();
+}
+
+/* ----- */
+
+int nb_disk=0;
+void handle_disk()
+{
+    disk_t *dp;
+    char *s, *fp;
+    int ch;
+    char *hostname = NULL, *diskname = NULL;
+
+    if(curprog != P_PLANNER && curprog != P_AMFLUSH) {
+       bogus_line();
+       return;
+    }
+
+    if(nb_disk==0) {
+       for(dp = diskq->head; dp != NULL; dp = dp->next)
+           dp->todo = 0;
+    }
+    nb_disk++;
+
+    s = curstr;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       return;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    hostname = newstralloc(hostname, fp);
+    s[-1] = ch;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       return;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    diskname = newstralloc(diskname, fp);
+    s[-1] = ch;
+
+    dp = lookup_disk(hostname, diskname);
+    if(dp == NULL) {
+       dp = add_disk(hostname, diskname);
+    }
+
+    amfree(hostname);
+    amfree(diskname);
+    dp->todo = 1;
+}
+
+repdata_t *handle_success()
+{
+    disk_t *dp;
+    float sec, kps, kbytes, origkb;
+    timedata_t *sp;
+    int i;
+    char *s, *fp;
+    int ch;
+    char *hostname = NULL;
+    char *diskname = NULL;
+    repdata_t *repdata;
+    int level;
+    char *datestamp;
+
+    if(curprog != P_TAPER && curprog != P_DUMPER && curprog != P_PLANNER) {
+       bogus_line();
+       return NULL;
+    }
+
+    s = curstr;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       return NULL;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    hostname = stralloc(fp);
+    s[-1] = ch;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       amfree(hostname);
+       return NULL;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    diskname = stralloc(fp);
+    s[-1] = ch;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       amfree(hostname);
+       amfree(diskname);
+       return NULL;
+    }
+    fp = s - 1;
+    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", &level) != 1) {
+           bogus_line();
+           amfree(hostname);
+           amfree(diskname);
+           amfree(datestamp);
+           return NULL;
+       }
+       skip_integer(s, ch);
+    }
+
+    skip_whitespace(s, ch);
+                               /* 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)  {
+           origkb = -1;
+           if(sscanf(s - 1,"[sec %f kb %f kps %f",
+                     &sec, &kbytes, &kps) != 3) {
+               bogus_line();
+               amfree(hostname);
+               amfree(diskname);
+               amfree(datestamp);
+               return NULL;
+           }
+       }
+       else {
+           if(origkb == 0.0) origkb = 0.1;
+       }
+    }
+
+
+    dp = lookup_disk(hostname, diskname);
+    if(dp == NULL) {
+       char *str = NULL;
+
+       str = vstralloc("  ", prefix(hostname, diskname, level),
+                       " ", "ERROR [not in disklist]",
+                       NULL);
+       addline(&errsum, str);
+       amfree(str);
+       amfree(hostname);
+       amfree(diskname);
+       amfree(datestamp);
+       return NULL;
+    }
+
+    repdata = find_repdata(dp, datestamp, level);
+
+    if(curprog == P_PLANNER) {
+       repdata->dumper.result = L_SKIPPED;
+       amfree(hostname);
+       amfree(diskname);
+       amfree(datestamp);
+       return repdata;
+    }
+
+    if(curprog == P_TAPER)
+       sp = &(repdata->taper);
+    else sp = &(repdata->dumper);
+
+    i = level > 0;
+
+    if(origkb == -1) {
+       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(atoi(datestamp) == Idatestamp) {
+           /* grab original size from record */
+           origkb = (double)inf.inf[level].size;
+       }
+       else
+           origkb = 0.0;
+    }
+    amfree(hostname);
+    amfree(diskname);
+    amfree(datestamp);
+
+    sp->result = L_SUCCESS;
+    sp->datestamp = repdata->datestamp;
+    sp->sec = sec;
+    sp->kps = kps;
+    sp->origsize = origkb;
+    sp->outsize = kbytes;
+
+    if(curprog == P_TAPER) {
+       if(current_tape == NULL) {
+           error("current_tape == NULL");
+       }
+       stats[i].taper_time += sec;
+       sp->filenum = ++tapefcount;
+       sp->tapelabel = current_tape->label;
+       tapedisks[level] +=1;
+       stats[i].tapedisks +=1;
+       stats[i].tapesize += kbytes;
+       current_tape->taper_time += sec;
+       current_tape->coutsize += kbytes;
+       current_tape->corigsize += origkb;
+       current_tape->tapedisks += 1;
+    }
+
+    if(curprog == P_DUMPER) {
+       stats[i].dumper_time += sec;
+       if(dp->compress == COMP_NONE) {
+           sp->origsize = kbytes;
+       }
+       else {
+           stats[i].coutsize += kbytes;
+           stats[i].corigsize += sp->origsize;
+       }
+       dumpdisks[level] +=1;
+       stats[i].dumpdisks +=1;
+       stats[i].origsize += sp->origsize;
+       stats[i].outsize += kbytes;
+    }
+
+    return repdata;
+}
+
+void handle_strange()
+{
+    char *str = NULL;
+    repdata_t *repdata;
+
+    repdata = handle_success();
+
+    str = vstralloc("  ", prefix(repdata->disk->host->hostname, 
+                                repdata->disk->name, repdata->level),
+                   " ", "STRANGE",
+                   NULL);
+    addline(&errsum, str);
+    amfree(str);
+
+    addline(&errdet,"");
+    str = vstralloc("/-- ", prefix(repdata->disk->host->hostname, 
+                                  repdata->disk->name, repdata->level),
+                   " ", "STRANGE",
+                   NULL);
+    addline(&errdet, str);
+    amfree(str);
+
+    while(contline_next()) {
+       get_logline(logfile);
+       addline(&errdet, curstr);
+    }
+    addline(&errdet,"\\--------");
+}
+
+void handle_failed()
+{
+    disk_t *dp;
+    char *hostname;
+    char *diskname;
+    char *datestamp;
+    char *errstr;
+    int level;
+    char *s, *fp;
+    int ch;
+    char *str = NULL;
+    repdata_t *repdata;
+    timedata_t *sp;
+
+    hostname = NULL;
+    diskname = NULL;
+
+    s = curstr;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       return;
+    }
+    hostname = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       return;
+    }
+    diskname = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       return;
+    }
+    fp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
+    datestamp = stralloc(fp);
+
+    if(strlen(datestamp) < 3) { /* there is no datestamp, it's the level */
+       level = atoi(datestamp);
+       datestamp = newstralloc(datestamp, run_datestamp);
+    }
+    else { /* read the level */
+       skip_whitespace(s, ch);
+       if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
+           bogus_line();
+           amfree(datestamp);
+           return;
+       }
+       skip_integer(s, ch);
+    }
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       bogus_line();
+       amfree(datestamp);
+       return;
+    }
+    errstr = s - 1;
+    if((s = strchr(errstr, '\n')) != NULL) {
+       *s = '\0';
+    }
+
+    dp = lookup_disk(hostname, diskname);
+    if(dp == NULL) {
+       str = vstralloc("  ", prefix(hostname, diskname, level),
+                       " ", "ERROR [not in disklist]",
+                       NULL);
+       addline(&errsum, str);
+       amfree(str);
+    } else {
+       repdata = find_repdata(dp, datestamp, level);
+
+       if(curprog == P_TAPER)
+           sp = &(repdata->taper);
+       else sp = &(repdata->dumper);
+
+       if(sp->result != L_SUCCESS)
+           sp->result = L_FAIL;
+    }
+    amfree(datestamp);
+
+    str = vstralloc("  ", prefix(hostname, diskname, level),
+                   " ", "FAILED",
+                   " ", errstr,
+                   NULL);
+    addline(&errsum, str);
+    amfree(str);
+
+    if(curprog == P_DUMPER) {
+       addline(&errdet,"");
+       str = vstralloc("/-- ", prefix(hostname, diskname, level),
+                       " ", "FAILED",
+                       " ", errstr,
+                       NULL);
+       addline(&errdet, str);
+       amfree(str);
+       while(contline_next()) {
+           get_logline(logfile);
+           addline(&errdet, curstr);
+       }
+       addline(&errdet,"\\--------");
+    }
+    return;
+}
+
+void generate_missing()
+{
+    disk_t *dp;
+    char *str = NULL;
+
+    for(dp = diskq->head; dp != NULL; dp = dp->next) {
+       if(dp->todo && data(dp) == NULL) {
+           str = vstralloc("  ", prefix(dp->host->hostname, dp->name, -987),
+                           " ", "RESULTS MISSING",
+                           NULL);
+           addline(&errsum, str);
+           amfree(str);
+       }
+    }
+}
+
+static char *
+prefix (host, disk, level)
+    char *host;
+    char *disk;
+    int level;
+{
+    char h[10+1];
+    int l;
+    char number[NUM_STR_SIZE];
+    static char *str = NULL;
+
+    ap_snprintf(number, sizeof(number), "%d", level);
+    if(host) {
+       strncpy(h, host, sizeof(h)-1);
+    } else {
+       strncpy(h, "(host?)", sizeof(h)-1);
+    }
+    h[sizeof(h)-1] = '\0';
+    for(l = strlen(h); l < sizeof(h)-1; l++) {
+       h[l] = ' ';
+    }
+    str = newvstralloc(str,
+                      h,
+                      " ", disk ? disk : "(disk?)",
+                      level != -987 ? " lev " : "",
+                      level != -987 ? number : "",
+                      NULL);
+    return str;
+}
+
+void copy_template_file(lbl_templ)
+char *lbl_templ;
+{
+  char buf[BUFSIZ];
+  int fd;
+  int numread;
+
+  if (strchr(lbl_templ, '/') == NULL) {
+    lbl_templ = stralloc2(config_dir, lbl_templ);
+  } else {
+    lbl_templ = stralloc(lbl_templ);
+  }
+  if ((fd = open(lbl_templ, 0)) < 0) {
+    curlog = L_ERROR;
+    curprog = P_REPORTER;
+    curstr = vstralloc("could not open PostScript template file ",
+                      lbl_templ,
+                      ": ",
+                      strerror(errno),
+                      NULL);
+    handle_error();
+    amfree(curstr);
+    afclose(postscript);
+    return;
+  }
+  while ((numread = read(fd, buf, sizeof(buf))) > 0) {
+    if (fwrite(buf, numread, 1, postscript) != 1) {
+      curlog = L_ERROR;
+      curprog = P_REPORTER;
+      curstr = vstralloc("error copying PostScript template file ",
+                        lbl_templ,
+                        ": ",
+                        strerror(errno),
+                        NULL);
+      handle_error();
+      amfree(curstr);
+      afclose(postscript);
+      return;
+    }
+  }
+  if (numread < 0) {
+    curlog = L_ERROR;
+    curprog = P_REPORTER;
+    curstr = vstralloc("error reading PostScript template file ",
+                      lbl_templ,
+                      ": ",
+                      strerror(errno),
+                      NULL);
+    handle_error();
+    amfree(curstr);
+    afclose(postscript);
+    return;
+  }
+  close(fd);
+  amfree(lbl_templ);
+}
+
+repdata_t *find_repdata(dp, datestamp, level)
+disk_t *dp;
+char *datestamp;
+int level;
+{
+    repdata_t *repdata, *prev;
+
+    if(!datestamp)
+       datestamp = run_datestamp;
+    prev = NULL;
+    for(repdata = data(dp); repdata != NULL && (repdata->level != level || strcmp(repdata->datestamp,datestamp)!=0); repdata = repdata->next) {
+       prev = repdata;
+    }
+    if(!repdata) {
+       repdata = (repdata_t *)alloc(sizeof(repdata_t));
+       memset(repdata, '\0',sizeof(repdata_t));
+       repdata->disk = dp;
+       repdata->datestamp = stralloc(datestamp ? datestamp : "");
+       repdata->level = level;
+       repdata->dumper.result = L_BOGUS;
+       repdata->taper.result = L_BOGUS;
+       repdata->next = NULL;
+       if(prev)
+           prev->next = repdata;
+       else
+           dp->up = (void *)repdata;
+    }
+    return repdata;
+}
+
+
+void do_postscript_output()
+{
+    tapetype_t *tp = lookup_tapetype(getconf_str(CNF_TAPETYPE));
+    disk_t *dp;
+    repdata_t *repdata;
+    float outsize, origsize;
+    int tapesize, marksize;
+
+    tapesize = tp->length;
+    marksize = tp->filemark;
+
+    for(current_tape = stats_by_tape; current_tape != NULL;
+           current_tape = current_tape->next) {
+
+       if (current_tape->label == NULL) {
+           break;
+       }
+
+       copy_template_file(tp->lbl_templ);
+
+       /* generate a few elements */
+       fprintf(postscript,"(%s) DrawDate\n\n",
+                   nicedate(run_datestamp ? atoi(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",
+             mb(current_tape->coutsize));
+       fprintf(postscript, "(Tape Used (%%)       ");
+       divzero(postscript, pct(current_tape->coutsize + 
+                               marksize * current_tape->tapedisks),
+                               tapesize);
+       fprintf(postscript," %%) DrawStat\n");
+       fprintf(postscript, "(Compression Ratio:  ");
+       divzero(postscript, pct(current_tape->coutsize),current_tape->corigsize);
+       fprintf(postscript," %%) DrawStat\n");
+       fprintf(postscript,"(Filesystems Taped: %4d) DrawStat\n",
+                 current_tape->tapedisks);
+
+       /* Summary */
+
+       fprintf(postscript,
+             "(-) (%s) (-) (  0) (      32) (      32) DrawHost\n",
+             current_tape->label);
+
+       for(dp = sortq.head; dp != NULL; dp = dp->next) {
+           if (dp->todo == 0) {
+                continue;
+           }
+           for(repdata = data(dp); repdata != NULL; repdata = repdata->next) {
+
+               if(repdata->taper.tapelabel != current_tape->label) {
+                   continue;
+               }
+
+               if(repdata->dumper.result == L_SUCCESS)
+                   origsize = repdata->dumper.origsize;
+               else
+                   origsize = repdata->taper.origsize;
+
+               if(repdata->taper.result == L_SUCCESS) 
+                   outsize  = repdata->taper.outsize;
+               else
+                   outsize  = repdata->dumper.outsize;
+
+               if (repdata->taper.result == L_SUCCESS) {
+                   if(origsize != 0.0) {
+                       fprintf(postscript,"(%s) (%s) (%d) (%3.0d) (%8.0f) (%8.0f) 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",
+                           dp->host->hostname, dp->name, repdata->level,
+                           repdata->taper.filenum, "N/A", 
+                           outsize);
+                   }
+               }
+           }
+       }
+       
+       fprintf(postscript,"\nshowpage\n");
+    }
+}
diff --git a/server-src/server_util.c b/server-src/server_util.c
new file mode 100644 (file)
index 0000000..fff4e6e
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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: server_util.c,v 1.1.2.1.4.2.2.3 2002/04/13 19:24:17 jrjackson Exp $
+ *
+ */
+
+#include "amanda.h"
+#include "server_util.h"
+#include "arglist.h"
+#include "token.h"
+
+const char *cmdstr[] = {
+    "BOGUS", "QUIT", "QUITTING", "DONE",
+    "FILE-DUMP", "PORT-DUMP", "CONTINUE", "ABORT",     /* dumper cmds */
+    "FAILED", "TRY-AGAIN", "NO-ROOM", "RQ-MORE-DISK",  /* dumper results */
+    "ABORT-FINISHED", "FATAL-TRYAGAIN", "BAD-COMMAND", /* dumper results */
+    "START-TAPER", "FILE-WRITE", "PORT-WRITE",         /* taper cmds */
+    "PORT", "TAPE-ERROR", "TAPER-OK",                  /* taper results */
+    NULL
+};
+
+cmd_t getcmd(cmdargs)
+struct cmdargs *cmdargs;
+{
+    char *line;
+    cmd_t cmd_i;
+
+    assert(cmdargs != NULL);
+
+    if (isatty(0)) {
+       printf("%s> ", get_pname());
+       fflush(stdout);
+    }
+
+    if ((line = agets(stdin)) == NULL) {
+       line = stralloc("QUIT");
+    }
+
+    cmdargs->argc = split(line, cmdargs->argv,
+       sizeof(cmdargs->argv) / sizeof(cmdargs->argv[0]), " ");
+    amfree(line);
+
+#if DEBUG
+    {
+       int i;
+       printf("argc = %d\n", cmdargs->argc);
+       for (i = 0; i < cmdargs->argc; i++)
+           printf("argv[%d] = \"%s\"\n", i, cmdargs->argv[i]);
+    }
+#endif
+
+    if (cmdargs->argc < 1)
+       return (BOGUS);
+
+    for(cmd_i=BOGUS; cmdstr[cmd_i] != NULL; cmd_i++)
+       if(strcmp(cmdargs->argv[1], cmdstr[cmd_i]) == 0)
+           return (cmd_i);
+    return (BOGUS);
+}
+
+
+printf_arglist_function1(void putresult, cmd_t, result, const char *, format)
+{
+    va_list argp;
+
+    arglist_start(argp, format);
+    printf("%s ",cmdstr[result]);
+    vprintf(format, argp);
+    fflush(stdout);
+    arglist_end(argp);
+}
+
diff --git a/server-src/server_util.h b/server-src/server_util.h
new file mode 100644 (file)
index 0000000..8e66b90
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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: server_util.h,v 1.1.2.1.4.2.2.2 2002/04/13 19:24:17 jrjackson Exp $
+ *
+ */
+#ifndef SERVER_UTIL_H
+#define        SERVER_UTIL_H
+
+#include "util.h"
+
+#define MAX_ARGS 32
+
+typedef enum {
+    BOGUS, QUIT, QUITTING, DONE,
+    FILE_DUMP, PORT_DUMP, CONTINUE, ABORT,             /* dumper cmds */
+    FAILED, TRYAGAIN, NO_ROOM, RQ_MORE_DISK,           /* dumper results */
+    ABORT_FINISHED, FATAL_TRYAGAIN, BAD_COMMAND,       /* dumper results */
+    START_TAPER, FILE_WRITE, PORT_WRITE,               /* taper cmds */
+    PORT, TAPE_ERROR, TAPER_OK,                                /* taper results */
+    LAST_TOK
+} cmd_t;
+extern const char *cmdstr[];
+
+struct cmdargs {
+    int argc;
+    char *argv[MAX_ARGS + 1];
+};
+
+cmd_t getcmd P((struct cmdargs *cmdargs));
+void putresult P((cmd_t result, const char *, ...))
+     __attribute__ ((format (printf, 2, 3)));
+
+#endif /* SERVER_UTIL_H */
diff --git a/server-src/tapefile.c b/server-src/tapefile.c
new file mode 100644 (file)
index 0000000..6d2b864
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * 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: tapefile.c,v 1.15.2.6.6.7 2003/10/24 13:44:49 martinea Exp $
+ *
+ * routines to read and write the amanda active tape list
+ */
+#include "amanda.h"
+#include "tapefile.h"
+#include "conffile.h"
+
+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));
+
+
+
+int read_tapelist(tapefile)
+char *tapefile;
+{
+    tape_t *tp;
+    FILE *tapef;
+    int pos;
+    char *line = NULL;
+    int status;
+
+    tape_list = NULL;
+    if((tapef = fopen(tapefile,"r")) == NULL) {
+       return 1;
+    }
+
+    while((line = agets(tapef)) != NULL) {
+       tp = parse_tapeline(&status, line);
+       amfree(line);
+       if(tp == NULL && status != 0) return 1;
+       if(tp != NULL) tape_list = insert(tape_list, tp);
+    }
+    afclose(tapef);
+
+    for(pos=1,tp=tape_list; tp != NULL; pos++,tp=tp->next) {
+       tp->position = pos;
+    }
+
+    return 0;
+}
+
+int write_tapelist(tapefile)
+char *tapefile;
+{
+    tape_t *tp;
+    FILE *tapef;
+    char *newtapefile;
+    int rc;
+
+    newtapefile = stralloc2(tapefile, ".new");
+
+    if((tapef = fopen(newtapefile,"w")) == NULL) {
+       amfree(newtapefile);
+       return 1;
+    }
+
+    for(tp = tape_list; tp != NULL; tp = tp->next) {
+       fprintf(tapef, "%d %s", tp->datestamp, tp->label);
+       if(tp->reuse) fprintf(tapef, " reuse");
+       else fprintf(tapef, " no-reuse");
+       fprintf(tapef, "\n");
+    }
+
+    if (fclose(tapef) == EOF) {
+       fprintf(stderr,"error [closing %s: %s]", newtapefile, strerror(errno));
+       return 1;
+    }
+    rc = rename(newtapefile, tapefile);
+    amfree(newtapefile);
+
+    return(rc != 0);
+}
+
+void clear_tapelist()
+{
+    tape_t *tp, *next;
+
+    for(tp = tape_list; tp; tp = next) {
+       amfree(tp->label);
+       next = tp->next;
+       amfree(tp);
+    }
+    tape_list = NULL;
+}
+
+tape_t *lookup_tapelabel(label)
+char *label;
+{
+    tape_t *tp;
+
+    for(tp = tape_list; tp != NULL; tp = tp->next) {
+       if(strcmp(label, tp->label) == 0) return tp;
+    }
+    return NULL;
+}
+
+
+
+tape_t *lookup_tapepos(pos)
+int pos;
+{
+    tape_t *tp;
+
+    for(tp = tape_list; tp != NULL; tp = tp->next) {
+       if(tp->position == pos) return tp;
+    }
+    return NULL;
+}
+
+
+tape_t *lookup_tapedate(datestamp)
+int datestamp;
+{
+    tape_t *tp;
+
+    for(tp = tape_list; tp != NULL; tp = tp->next) {
+       if(tp->datestamp == datestamp) return tp;
+    }
+    return NULL;
+}
+
+int lookup_nb_tape()
+{
+    tape_t *tp;
+    int pos=0;
+
+    for(tp = tape_list; tp != NULL; tp = tp->next) {
+       pos=tp->position;
+    }
+    return pos;
+}
+
+tape_t *lookup_last_reusable_tape(skip)
+     int skip;
+{
+    tape_t *tp, **tpsave;
+    int count=0;
+    int s;
+    int tapecycle = getconf_int(CNF_TAPECYCLE);
+    char *labelstr = getconf_str (CNF_LABELSTR);
+
+    /*
+     * The idea here is we keep the last "several" reusable tapes we
+     * find in a stack and then return the n-th oldest one to the
+     * 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));
+    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)) {
+           count++;
+           for(s = skip; s > 0; s--) {
+               tpsave[s] = tpsave[s - 1];
+           }
+           tpsave[0] = tp;
+       }
+    }
+    s = tapecycle - count;
+    if(s < 0) s = 0;
+    if(count < tapecycle - skip) tp = NULL;
+    else tp = tpsave[skip - s];
+    amfree(tpsave);
+    return tp;
+}
+
+int reusable_tape(tp)
+    tape_t *tp;
+{
+    int count = 0;
+
+    if(tp == NULL) return 0;
+    if(tp->reuse == 0) return 0;
+    if(tp->datestamp == 0) return 1;
+    while(tp != NULL) {
+       if(tp->reuse == 1) count++;
+       tp = tp->prev;
+    }
+    return (count >= getconf_int(CNF_TAPECYCLE));
+}
+
+void remove_tapelabel(label)
+char *label;
+{
+    tape_t *tp, *prev, *next;
+
+    tp = lookup_tapelabel(label);
+    if(tp != NULL) {
+       prev = tp->prev;
+       next = tp->next;
+       if(prev != NULL)
+           prev->next = next;
+       else /* begin of list */
+           tape_list = next;
+       if(next != NULL)
+           next->prev = prev;
+       while (next != NULL) {
+           next->position--;
+           next = next->next;
+       }
+       amfree(tp->label);
+       amfree(tp);
+    }
+}
+
+tape_t *add_tapelabel(datestamp, label)
+int 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->datestamp = datestamp;
+    new->position = 0;
+    new->reuse = 1;
+    new->label = stralloc(label);
+
+    new->prev  = NULL;
+    if(tape_list != NULL) tape_list->prev = new;
+    new->next = tape_list;
+    tape_list = new;
+
+    /* scan list, updating positions */
+    cur = tape_list;
+    while(cur != NULL) {
+       cur->position++;
+       cur = cur->next;
+    }
+
+    return new;
+}
+
+int guess_runs_from_tapelist()
+{
+    tape_t *tp;
+    int i, ntapes, tape_ndays, dumpcycle, runtapes, runs;
+    time_t tape_time, today;
+
+    today = time(0);
+    dumpcycle = getconf_int(CNF_DUMPCYCLE);
+    runtapes = getconf_int(CNF_RUNTAPES);
+    if(runtapes == 0) runtapes = 1;    /* just in case */
+
+    ntapes = 0;
+    tape_ndays = 0;
+    for(i = 1; i < getconf_int(CNF_TAPECYCLE); i++) {
+       if((tp = lookup_tapepos(i)) == NULL) break;
+
+       tape_time  = stamp2time(tp->datestamp);
+       tape_ndays = days_diff(tape_time, today);
+
+       if(tape_ndays < dumpcycle) ntapes++;
+       else break;
+    }
+
+    if(tape_ndays < dumpcycle) {
+       /* scale for best guess */
+       if(tape_ndays == 0) ntapes = dumpcycle * runtapes;
+       else ntapes = ntapes * dumpcycle / tape_ndays;
+    }
+    else if(ntapes == 0) {
+       /* no dumps within the last dumpcycle, guess as above */
+       ntapes = dumpcycle * runtapes;
+    }
+
+    runs = (ntapes + runtapes - 1) / runtapes;
+    if (runs <= 0)
+      runs = 1;
+    return runs;
+}
+
+static tape_t *parse_tapeline(status, line)
+int *status;
+char *line;
+{
+    tape_t *tp = NULL;
+    char *s, *s1;
+    int ch;
+
+    *status = 0;
+    tp = (tape_t *) alloc(sizeof(tape_t));
+
+    tp->prev = NULL;
+    tp->next = NULL;
+
+    s = line;
+    ch = *s++;
+
+    skip_whitespace(s, ch);
+    if(ch == '\0') {
+       amfree(tp);
+       return NULL;
+    }
+    if (sscanf(s - 1, "%d", &tp->datestamp) != 1) {
+       amfree(tp);
+       *status = 1;
+       return NULL;
+    }
+    skip_integer(s, ch);
+
+    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)
+       tp->reuse = 1;
+#undef sc
+#define sc "no-reuse"
+    if(strncmp(s - 1, sc, sizeof(sc)-1) == 0)
+       tp->reuse = 0;
+#undef sc
+
+    return tp;
+}
+
+
+/* insert in reversed datestamp order */
+static tape_t *insert(list, tp)
+tape_t *list, *tp;
+{
+    tape_t *prev, *cur;
+
+    prev = NULL;
+    cur = list;
+
+    while(cur != NULL && cur->datestamp >= tp->datestamp) {
+       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;
+
+    return list;
+}
+
+
+static time_t stamp2time(datestamp)
+int datestamp;
+/*
+ * Converts datestamp (an int of the form YYYYMMDD) 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.
+ */
+{
+    struct tm tm;
+    time_t now;
+
+    now = time(0);
+    tm = *localtime(&now);     /* initialize sec/min/hour & gmtoff */
+
+    tm.tm_year = ( datestamp          / 10000) - 1900;
+    tm.tm_mon  = ((datestamp % 10000) /   100) - 1;
+    tm.tm_mday = ((datestamp %   100)        );
+
+    return mktime(&tm);
+}
diff --git a/server-src/tapefile.h b/server-src/tapefile.h
new file mode 100644 (file)
index 0000000..875ab51
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: tapefile.h,v 1.6 1998/09/11 23:25:32 jrj Exp $
+ *
+ * interface for active tape list manipulation routines
+ */
+#ifndef TAPEFILE_H
+#define TAPEFILE_H
+
+#include "amanda.h"
+
+typedef struct tape_s {
+    struct tape_s *next, *prev;
+    int position;
+    int 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(());
+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 guess_runs_from_tapelist P((void));
+
+#endif /* !TAPEFILE_H */
diff --git a/server-src/taper.c b/server-src/taper.c
new file mode 100644 (file)
index 0000000..ec84069
--- /dev/null
@@ -0,0 +1,2264 @@
+/*
+ * 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: taper.c,v 1.47.2.14.4.8.2.18 2004/02/13 14:11:26 martinea Exp $
+ *
+ * moves files from holding disk to tape, or from a socket to tape
+ */
+
+#include "amanda.h"
+#include "conffile.h"
+#include "tapefile.h"
+#include "clock.h"
+#include "stream.h"
+#include "logfile.h"
+#include "tapeio.h"
+#include "changer.h"
+#include "version.h"
+#include "arglist.h"
+#include "token.h"
+#include "amfeatures.h"
+#include "fileheader.h"
+#include "server_util.h"
+#ifdef HAVE_LIBVTBLC
+#include <vtblc.h>
+#include <strings.h>
+
+static int vtbl_no   = -1;
+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;
+typedef struct vtbl_lbls {
+    u_int8_t  label[45];
+    u_int8_t  date[20];
+} vtbl_lbls;
+static vtbl_lbls vtbl_entry[MAX_VOLUMES];
+#endif /* HAVE_LIBVTBLC */
+/*
+ * XXX update stat collection/printing
+ * XXX advance to next tape first in next_tape
+ * XXX label is being read twice?
+ */
+
+/* NBUFS replaced by conf_tapebufs */
+/* #define NBUFS               20 */
+int conf_tapebufs;
+
+/* 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;
+    char *buffer;
+} buffer_t;
+
+#define nextbuf(p)    ((p) == buftable+conf_tapebufs-1? buftable : (p)+1)
+#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));
+
+/* shared-memory routines */
+char *attach_buffers P((unsigned int size));
+void detach_buffers P((char *bufp));
+void destroy_buffers P((void));
+
+/* synchronization pipe routines */
+void syncpipe_init P((int rd, int wr));
+char syncpipe_get P((void));
+int  syncpipe_getint P((void));
+char *syncpipe_getstr P((void));
+void syncpipe_put P((int ch));
+void syncpipe_putint P((int i));
+void syncpipe_putstr P((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));
+
+/*
+ * ========================================================================
+ * GLOBAL STATE
+ *
+ */
+int interactive;
+int writerpid;
+times_t total_wait;
+#ifdef TAPER_DEBUG
+int bufdebug = 1;
+#else
+int bufdebug = 0;
+#endif
+
+char *buffers = NULL;
+buffer_t *buftable = NULL;
+
+char *procname = "parent";
+
+char *taper_datestamp = NULL;
+char *label = NULL;
+int filenum;
+char *errstr = NULL;
+int tape_fd = -1;
+char *tapedev = NULL;
+char *tapetype = NULL;
+tapetype_t *tt = NULL;
+long tt_blocksize;
+long tt_blocksize_kb;
+long buffer_size;
+int tt_file_pad;
+static unsigned long malloc_hist_1, malloc_size_1;
+static unsigned long malloc_hist_2, malloc_size_2;
+
+am_feature_t *their_features = NULL;
+
+int runtapes, cur_tape, have_changer, tapedays;
+char *labelstr, *conf_tapelist;
+#ifdef HAVE_LIBVTBLC
+char *rawtapedev;
+int first_seg, last_seg;
+#endif /* HAVE_LIBVTBLC */
+
+/*
+ * ========================================================================
+ * MAIN PROGRAM
+ *
+ */
+int main(main_argc, main_argv)
+int main_argc;
+char **main_argv;
+{
+    int p2c[2], c2p[2];                /* parent-to-child, child-to-parent pipes */
+    char *conffile;
+    int fd;
+    unsigned int size;
+    int i;
+    int j;
+    int page_size;
+    char *first_buffer;
+
+    for(fd = 3; fd < 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
+        * descriptor, which in turn might be used as an index into
+        * an array (e.g. an fd_set).
+        */
+       close(fd);
+    }
+
+    set_pname("taper");
+
+    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+
+    fprintf(stderr, "%s: pid %ld executable %s version %s\n",
+           get_pname(), (long) getpid(), main_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++;
+    } else {
+       char my_cwd[STR_SIZE];
+
+       if (getcwd(my_cwd, sizeof(my_cwd)) == NULL) {
+           error("cannot determine current working directory");
+       }
+       config_dir = stralloc2(my_cwd, "/");
+       if ((config_name = strrchr(my_cwd, '/')) != NULL) {
+           config_name = stralloc(config_name + 1);
+       }
+    }
+
+    safe_cd();
+
+    /* print prompts and debug messages if running interactive */
+
+    interactive = (main_argc > 1 && strcmp(main_argv[1],"-t") == 0);
+    if(interactive) {
+       erroutput_type = ERR_INTERACTIVE;
+    } else {
+       erroutput_type = ERR_AMANDALOG;
+       set_logerror(logerror);
+    }
+
+    conffile = stralloc2(config_dir, CONFFILE_NAME);
+    if(read_conffile(conffile)) {
+       error("errors processing config file \"%s\"", conffile);
+    }
+    amfree(conffile);
+
+    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 load tapelist \"%s\"", conf_tapelist);
+    }
+
+    tapedev    = getconf_str(CNF_TAPEDEV);
+    tapetype    = getconf_str(CNF_TAPETYPE);
+    tt         = lookup_tapetype(tapetype);
+#ifdef HAVE_LIBVTBLC
+    rawtapedev = getconf_str(CNF_RAWTAPEDEV);
+#endif /* HAVE_LIBVTBLC */
+    tapedays   = getconf_int(CNF_TAPECYCLE);
+    labelstr   = getconf_str(CNF_LABELSTR);
+
+    runtapes   = getconf_int(CNF_RUNTAPES);
+    cur_tape   = 0;
+
+    conf_tapebufs = getconf_int(CNF_TAPEBUFS);
+
+    tt_blocksize_kb = tt->blocksize;
+    tt_blocksize = tt_blocksize_kb * 1024;
+    tt_file_pad = tt->file_pad;
+
+    if(interactive) {
+       fprintf(stderr,"taper: running in interactive test mode\n");
+       fflush(stderr);
+    }
+
+    /* create read/write syncronization pipes */
+
+    if(pipe(p2c) || pipe(c2p))
+       error("creating sync pipes: %s", strerror(errno));
+
+    /* create shared memory segment */
+
+#if defined(HAVE_GETPAGESIZE)
+    page_size = getpagesize();
+    fprintf(stderr, "%s: page size is %d\n", get_pname(), page_size);
+#else
+    page_size = 1024;
+    fprintf(stderr, "%s: getpagesize() not available, using %d\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) {
+       size  = page_size;
+       size += conf_tapebufs * buffer_size;
+       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",
+                       conf_tapebufs,
+                       (conf_tapebufs == 1) ? "" : "s",
+                       size,
+                       strerror(errno));
+       conf_tapebufs--;
+    }
+    if(buffers == NULL) {
+       error("cannot allocate shared memory");
+    }
+    i = (buffers - (char *)0) & (page_size - 1);  /* page boundary offset */
+    if(i != 0) {
+       first_buffer = buffers + page_size - i;
+       fprintf(stderr, "%s: shared memory at %p, first buffer at %p\n",
+               get_pname(),
+               buffers,
+               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) {
+       j = 1;
+    } else if(conf_tapebufs < 100) {
+       j = 2;
+    } else {
+       j = 3;
+    }
+    for(i = 0; i < conf_tapebufs; i++) {
+       buftable[i].buffer = first_buffer + i * buffer_size;
+       fprintf(stderr, "%s: buffer[%0*d] at %p\n",
+               get_pname(),
+               j, i,
+               buftable[i].buffer);
+    }
+    fprintf(stderr, "%s: buffer structures at %p for %d bytes\n",
+           get_pname(),
+           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));
+
+    case 0:    /* child */
+       aclose(p2c[1]);
+       aclose(c2p[0]);
+
+       tape_writer_side(p2c[0], c2p[1]);
+       error("tape writer terminated unexpectedly");
+
+    default:   /* parent */
+       aclose(p2c[0]);
+       aclose(c2p[1]);
+
+       file_reader_side(c2p[0], p2c[1]);
+       error("file reader terminated unexpectedly");
+    }
+
+    /* NOTREACHED */
+    return 0;
+}
+
+
+/*
+ * ========================================================================
+ * FILE READER SIDE
+ *
+ */
+void read_file P((int fd, char *handle,
+                 char *host, char *disk, char *datestamp, 
+                 int level, int port_flag));
+int taper_fill_buffer P((int fd, buffer_t *bp, int buflen));
+void dumpbufs P((char *str1));
+void dumpstatus P((buffer_t *bp));
+
+void file_reader_side(rdpipe, wrpipe)
+int rdpipe, wrpipe;
+{
+    cmd_t cmd;
+    struct cmdargs cmdargs;
+    char *handle = NULL;
+    char *filename = NULL;
+    char *hostname = NULL;
+    char *diskname = NULL;
+    char *result = NULL;
+    char *datestamp = NULL;
+    char tok;
+    char *q = NULL;
+    int level, fd, data_port, data_socket, wpid;
+    struct stat stat_file;
+    int tape_started;
+    int a;
+
+    procname = "reader";
+    syncpipe_init(rdpipe, wrpipe);
+
+    /* must get START_TAPER before beginning */
+
+    startclock();
+    cmd = getcmd(&cmdargs);
+    total_wait = stopclock();
+
+    if(cmd != START_TAPER || cmdargs.argc != 2) {
+       error("error [file_reader_side cmd %d argc %d]", cmd, cmdargs.argc);
+    }
+
+    /* pass start command on to tape writer */
+
+    taper_datestamp = newstralloc(taper_datestamp, cmdargs.argv[2]);
+
+    tape_started = 0;
+    syncpipe_put('S');
+    syncpipe_putstr(taper_datestamp);
+
+    /* get result of start command */
+
+    tok = syncpipe_get();
+    switch(tok) {
+    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]", result);
+       amfree(result);
+       syncpipe_put('e');                      /* ACK error */
+       break;
+    default:
+       error("expected 'S' or 'E' for START-TAPER, got '%c'", tok);
+    }
+
+    /* process further commands */
+
+    while(1) {
+       startclock();
+       cmd = getcmd(&cmdargs);
+       if(cmd != QUIT && !tape_started) {
+           error("error [file_reader_side cmd %d without tape ready]", cmd);
+       }
+       total_wait = timesadd(total_wait, stopclock());
+
+       switch(cmd) {
+       case PORT_WRITE:
+           /*
+            * PORT-WRITE
+            *   handle
+            *   hostname
+            *   features
+            *   diskname
+            *   level
+            *   datestamp
+            */
+           cmdargs.argc++;                     /* true count of args */
+           a = 2;
+
+           if(a >= cmdargs.argc) {
+               error("error [taper PORT-WRITE: not enough args: handle]");
+           }
+           handle = newstralloc(handle, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper PORT-WRITE: not enough args: hostname]");
+           }
+           hostname = newstralloc(hostname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper PORT-WRITE: not enough args: features]");
+           }
+           am_release_feature_set(their_features);
+           their_features = am_string_to_feature(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper PORT-WRITE: not enough args: diskname]");
+           }
+           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper PORT-WRITE: not enough args: level]");
+           }
+           level = atoi(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper PORT-WRITE: not enough args: datestamp]");
+           }
+           datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
+
+           if(a != cmdargs.argc) {
+               error("error [taper file_reader_side PORT-WRITE: too many args: %d != %d]",
+                     cmdargs.argc, a);
+           }
+
+           data_port = 0;
+           data_socket = stream_server(&data_port,
+                                       -1,
+                                       STREAM_BUFSIZE);        
+           if(data_socket < 0) {
+               char *m;
+
+               m = vstralloc("[port create failure: ",
+                             strerror(errno),
+                             "]",
+                             NULL);
+               q = squote(m);
+               putresult(TAPE_ERROR, "%s %s\n", handle, q);
+               amfree(m);
+               break;
+           }
+           putresult(PORT, "%d\n", data_port);
+
+           if((fd = stream_accept(data_socket, CONNECT_TIMEOUT,
+                                  -1, NETWORK_BLOCK_BYTES)) == -1) {
+               q = squote("[port connect timeout]");
+               putresult(TAPE_ERROR, "%s %s\n", handle, q);
+               aclose(data_socket);
+               break;
+           }
+           read_file(fd, handle, hostname, diskname, datestamp, level, 1);
+           aclose(data_socket);
+           break;
+
+       case FILE_WRITE:
+           /*
+            * FILE-WRITE
+            *   handle
+            *   filename
+            *   hostname
+            *   features
+            *   diskname
+            *   level
+            *   datestamp
+            */
+           cmdargs.argc++;                     /* true count of args */
+           a = 2;
+
+           if(a >= cmdargs.argc) {
+               error("error [taper FILE-WRITE: not enough args: handle]");
+           }
+           handle = newstralloc(handle, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper FILE-WRITE: not enough args: filename]");
+           }
+           filename = newstralloc(filename, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper FILE-WRITE: not enough args: hostname]");
+           }
+           hostname = newstralloc(hostname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper FILE-WRITE: not enough args: features]");
+           }
+           am_release_feature_set(their_features);
+           their_features = am_string_to_feature(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper FILE-WRITE: not enough args: diskname]");
+           }
+           diskname = newstralloc(diskname, cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper FILE-WRITE: not enough args: level]");
+           }
+           level = atoi(cmdargs.argv[a++]);
+
+           if(a >= cmdargs.argc) {
+               error("error [taper FILE-WRITE: not enough args: datestamp]");
+           }
+           datestamp = newstralloc(datestamp, cmdargs.argv[a++]);
+
+           if(a != cmdargs.argc) {
+               error("error [taper file_reader_side FILE-WRITE: too many args: %d != %d]",
+                     cmdargs.argc, a);
+           }
+
+           if(stat(filename,&stat_file)!=0) {
+               q = squotef("[%s]", strerror(errno));
+               putresult(TAPE_ERROR, "%s %s\n", handle, q);
+               break;
+           }
+           if((fd = open(filename, O_RDONLY)) == -1) {
+               q = squotef("[%s]", strerror(errno));
+               putresult(TAPE_ERROR, "%s %s\n", handle, q);
+               break;
+           }
+           read_file(fd, handle, hostname, diskname, datestamp, level, 0);
+           break;
+
+       case QUIT:
+           putresult(QUITTING, "\n");
+           fprintf(stderr,"taper: DONE [idle wait: %s secs]\n",
+                   walltime_str(total_wait));
+           fflush(stderr);
+           syncpipe_put('Q');  /* tell writer we're exiting gracefully */
+           aclose(wrpipe);
+
+           if((wpid = wait(NULL)) != writerpid) {
+               fprintf(stderr,
+                       "taper: writer wait returned %d instead of %d: %s\n",
+                       wpid, writerpid, strerror(errno));
+               fflush(stderr);
+           }
+
+           detach_buffers(buffers);
+           destroy_buffers();
+           amfree(datestamp);
+           amfree(label);
+           amfree(errstr);
+           amfree(changer_resultstr);
+           amfree(tapedev);
+           amfree(config_dir);
+           amfree(config_name);
+
+           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);
+           }
+
+           exit(0);
+
+       default:
+           if(cmdargs.argc >= 1) {
+               q = squote(cmdargs.argv[1]);
+           } else if(cmdargs.argc >= 0) {
+               q = squote(cmdargs.argv[0]);
+           } else {
+               q = stralloc("(no input?)");
+           }
+           putresult(BAD_COMMAND, "%s\n", q);
+           break;
+       }
+    }
+    amfree(q);
+    amfree(handle);
+    amfree(filename);
+    amfree(hostname);
+    amfree(diskname);
+}
+
+void dumpbufs(str1)
+char *str1;
+{
+    int i,j;
+    long v;
+
+    fprintf(stderr, "%s: state", str1);
+    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++);
+       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;
+       default:
+           fprintf(stderr, "%ld", v);
+           break;
+       }
+
+    }
+    fputc('\n', stderr);
+    fflush(stderr);
+}
+
+void dumpstatus(bp)
+buffer_t *bp;
+{
+    char pn[2];
+    char bt[NUM_STR_SIZE];
+    char status[NUM_STR_SIZE + 1];
+    char *str = NULL;
+
+    pn[0] = procname[0];
+    pn[1] = '\0';
+    ap_snprintf(bt, sizeof(bt), "%d", (int)(bp-buftable));
+
+    switch(bp->status) {
+    case FULL:         ap_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;
+    default:
+       ap_snprintf(status, sizeof(status), "%ld", bp->status);
+       break;
+    }
+
+    str = vstralloc("taper: ", pn, ": [buf ", bt, ":=", status, "]", NULL);
+    dumpbufs(str);
+    amfree(str);
+}
+
+
+void read_file(fd, handle, hostname, diskname, datestamp, level, port_flag)
+    int fd, level, port_flag;
+    char *handle, *hostname, *diskname, *datestamp;
+{
+    buffer_t *bp;
+    char tok;
+    int rc, err, opening, closing, bufnum, need_closing;
+    long filesize;
+    times_t runtime;
+    char *strclosing = NULL;
+    char *str;
+    int header_read = 0;
+    int buflen;
+    dumpfile_t file;
+
+    char *q = NULL;
+
+#ifdef HAVE_LIBVTBLC
+    static char desc[45];
+    static char vol_date[20];
+    static char vol_label[45];
+#endif /* HAVE_LIBVTBLC */
+
+
+    /* initialize */
+
+    filesize = 0;
+    closing = 0;
+    need_closing = 0;
+    err = 0;
+    fh_init(&file);
+
+    if(bufdebug) {
+       fprintf(stderr, "taper: r: start file\n");
+       fflush(stderr);
+    }
+
+    for(bp = buftable; bp < buftable + conf_tapebufs; bp++) {
+       bp->status = EMPTY;
+    }
+
+    bp = buftable;
+    if(interactive || bufdebug) dumpstatus(bp);
+
+    /* tell writer to open tape */
+
+    opening = 1;
+    syncpipe_put('O');
+    syncpipe_putstr(datestamp);
+    syncpipe_putstr(hostname);
+    syncpipe_putstr(diskname);
+    syncpipe_putint(level);
+
+    startclock();
+
+    /* read file in loop */
+
+    while(1) {
+       tok = syncpipe_get();
+       switch(tok) {
+
+       case 'O':
+           assert(opening);
+           opening = 0;
+           err = 0;
+           break;
+
+       case 'R':
+           bufnum = syncpipe_getint();
+
+           if(bufdebug) {
+               fprintf(stderr, "taper: r: got R%d\n", bufnum);
+               fflush(stderr);
+           }
+
+           if(need_closing) {
+               syncpipe_put('C');
+               closing = 1;
+               need_closing = 0;
+               break;
+           }
+
+           if(closing) break;  /* ignore extra read tokens */
+
+           assert(!opening);
+           if(bp->status != EMPTY || bufnum != 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, "    my buf %d but writer buf %d\n",
+                           (int)(bp-buftable), bufnum);
+               }
+               else {
+                   fprintf(stderr,"buf %d state %s (%ld) instead of EMPTY\n",
+                           (int)(bp-buftable),
+                           bp->status == FILLING? "FILLING" :
+                           bp->status == FULL? "FULL" : "EMPTY!?!?",
+                           (long)bp->status);
+               }
+               dumpbufs("taper");
+               sleep(1);
+               dumpbufs("taper: after 1 sec");
+               if(bp->status == EMPTY)
+                   fprintf(stderr, "taper: result now correct!\n");
+               fflush(stderr);
+
+               errstr = newstralloc(errstr,
+                                    "[fatal buffer mismanagement bug]");
+               q = squote(errstr);
+               putresult(TRYAGAIN, "%s %s\n", handle, q);
+               amfree(q);
+               log_add(L_INFO, "retrying %s:%s.%d on new tape: %s",
+                       hostname, diskname, level, errstr);
+               closing = 1;
+               syncpipe_put('X');      /* X == buffer snafu, bail */
+               do {
+                   tok = syncpipe_get();
+                   if(tok == 'R')
+                       bufnum = syncpipe_getint();
+               } while(tok != 'x');
+               aclose(fd);
+               return;
+           }
+
+           bp->status = FILLING;
+           buflen = header_read ? tt_blocksize : DISK_BLOCK_BYTES;
+           if(interactive || bufdebug) dumpstatus(bp);
+           if((rc = taper_fill_buffer(fd, bp, buflen)) < 0) {
+               err = errno;
+               closing = 1;
+               strclosing = newvstralloc(strclosing,"Can't read data: ",NULL);
+               syncpipe_put('C');
+           } else {
+               if(rc < buflen) { /* switch to next file */
+                   int save_fd;
+                   struct stat stat_file;
+
+                   save_fd = fd;
+                   close(fd);
+                   if(file.cont_filename[0] == '\0') { /* no more file */
+                       err = 0;
+                       need_closing = 1;
+                   } else if(stat(file.cont_filename, &stat_file) != 0) {
+                       err = errno;
+                       need_closing = 1;
+                       strclosing = newvstralloc(strclosing,"can't stat: ",file.cont_filename,NULL);
+                   } else if((fd = open(file.cont_filename,O_RDONLY)) == -1) {
+                       err = errno;
+                       need_closing = 1;
+                       strclosing = newvstralloc(strclosing,"can't open: ",file.cont_filename,NULL);
+                   } else if((fd != save_fd) && dup2(fd, save_fd) == -1) {
+                       err = errno;
+                       need_closing = 1;
+                       strclosing = newvstralloc(strclosing,"can't dup2: ",file.cont_filename,NULL);
+                   } else {
+                       buffer_t bp1;
+                       int rc1;
+
+                       bp1.status = EMPTY;
+                       bp1.size = DISK_BLOCK_BYTES;
+                       bp1.buffer = malloc(DISK_BLOCK_BYTES);
+
+                       if(fd != save_fd) {
+                           close(fd);
+                           fd = save_fd;
+                       }
+
+                       rc1 = taper_fill_buffer(fd, &bp1, DISK_BLOCK_BYTES);
+                       if(rc1 <= 0) {
+                           amfree(bp1.buffer);
+                           err = (rc1 < 0) ? errno : 0;
+                           need_closing = 1;
+                           strclosing = newvstralloc(strclosing,
+                                                     "Can't read header: ",
+                                                     file.cont_filename,
+                                                     NULL);
+                       } else {
+                           parse_file_header(bp1.buffer, &file, rc1);
+
+                           amfree(bp1.buffer);
+                           bp1.buffer = bp->buffer + rc;
+
+                           rc1 = taper_fill_buffer(fd, &bp1, tt_blocksize - rc);
+                           if(rc1 <= 0) {
+                               err = (rc1 < 0) ? errno : 0;
+                               need_closing = 1;
+                               if(rc1 < 0) {
+                                   strclosing = newvstralloc(strclosing,
+                                                             "Can't read data: ",
+                                                             file.cont_filename,
+                                                             NULL);
+                               }
+                           }
+                           else {
+                               rc += rc1;
+                               bp->size = rc;
+                           }
+                       }
+                   }
+               }
+               if(rc > 0) {
+                   bp->status = FULL;
+                   if(header_read == 0) {
+                       char *cont_filename;
+
+                       parse_file_header(bp->buffer, &file, rc);
+                       cont_filename = stralloc(file.cont_filename);
+                       file.cont_filename[0] = '\0';
+                       file.blocksize = tt_blocksize;
+                       build_header(bp->buffer, &file, tt_blocksize);
+
+                       /* 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 */
+                       header_read = 1;
+                       amfree(cont_filename);
+                   }
+                   else {
+                       filesize += am_round(rc, 1024) / 1024;
+                   }
+                   if(interactive || bufdebug) dumpstatus(bp);
+                   if(bufdebug) {
+                       fprintf(stderr,"taper: r: put W%d\n",(int)(bp-buftable));
+                       fflush(stderr);
+                   }
+                   syncpipe_put('W');
+                   syncpipe_putint(bp-buftable);
+                   bp = nextbuf(bp);
+               }
+               if(need_closing && rc <= 0) {
+                   syncpipe_put('C');
+                   need_closing = 0;
+                   closing = 1;
+               }
+           }
+           break;
+
+       case 'T':
+       case 'E':
+           syncpipe_put('e');  /* ACK error */
+
+           aclose(fd);
+           str = syncpipe_getstr();
+           errstr = newvstralloc(errstr, "[", str ? str : "(null)", "]", NULL);
+           amfree(str);
+
+           q = squote(errstr);
+           if(tok == 'T') {
+               putresult(TRYAGAIN, "%s %s\n", handle, q);
+               log_add(L_INFO, "retrying %s:%s.%d on new tape: %s",
+                       hostname, diskname, level, errstr);
+           } else {
+               putresult(TAPE_ERROR, "%s %s\n", handle, q);
+               log_add(L_FAIL, "%s %s %s %d [out of tape]",
+                       hostname, diskname, datestamp, level);
+               log_add(L_ERROR,"no-tape [%s]", errstr);
+           }
+           amfree(q);
+           return;
+
+       case 'C':
+           assert(!opening);
+           assert(closing);
+
+           str = syncpipe_getstr();
+           label = newstralloc(label, str ? str : "(null)");
+           amfree(str);
+           str = syncpipe_getstr();
+           filenum = atoi(str ? str : "-9876");        /* ??? */
+           amfree(str);
+           fprintf(stderr, "taper: reader-side: got label %s filenum %d\n",
+                   label, filenum);
+           fflush(stderr);
+
+           aclose(fd);
+           runtime = stopclock();
+           if(err) {
+               if(strclosing) {
+                   errstr = newvstralloc(errstr,
+                                         "[input: ", strclosing, ": ",
+                                         strerror(err), "]", NULL);
+                   amfree(strclosing);
+               }
+               else
+                   errstr = newvstralloc(errstr,
+                                         "[input: ", strerror(err), "]",
+                                         NULL);
+               q = squote(errstr);
+               putresult(TAPE_ERROR, "%s %s\n", handle, q);
+               amfree(q);
+               log_add(L_FAIL, "%s %s %s %d %s",
+                       hostname, diskname, datestamp, level, errstr);
+               str = syncpipe_getstr();        /* reap stats */
+               amfree(str);
+           } else {
+               char kb_str[NUM_STR_SIZE];
+               char kps_str[NUM_STR_SIZE];
+               double rt;
+
+               rt = runtime.r.tv_sec+runtime.r.tv_usec/1000000.0;
+               ap_snprintf(kb_str, sizeof(kb_str), "%ld", filesize);
+               ap_snprintf(kps_str, sizeof(kps_str), "%3.1f",
+                                    rt ? filesize / rt : 0.0);
+               str = syncpipe_getstr();
+               errstr = newvstralloc(errstr,
+                                     "[sec ", walltime_str(runtime),
+                                     " kb ", kb_str,
+                                     " kps ", kps_str,
+                                     " ", str ? str : "(null)",
+                                     "]",
+                                     NULL);
+               amfree(str);
+               q = squote(errstr);
+               putresult(DONE, "%s %s %d %s\n",
+                         handle, label, filenum, q);
+               amfree(q);
+               log_add(L_SUCCESS, "%s %s %s %d %s",
+                       hostname, diskname, datestamp, level, errstr);
+#ifdef HAVE_LIBVTBLC
+               /* 
+                *  We have 44 characters available for the label string:
+                *  use max 20 characters for hostname
+                *      max 20 characters for diskname 
+                *             (it could contain a samba share or dos path)
+                *           2 for level
+                */
+               memset(desc, '\0', 45);
+
+               strncpy(desc, hostname, 20);
+
+               if ((len = strlen(hostname)) <= 20) {
+                   memset(desc + len, ' ', 1);
+                   offset = len + 1;
+               }
+               else{
+                   memset(desc + 20, ' ', 1);
+                   offset = 21;
+               }
+
+               strncpy(desc + offset, diskname, 20);
+
+               if ((len = strlen(diskname)) <= 20) {
+                   memset(desc + offset + len, ' ', 1);
+                   offset = offset + len + 1;
+               }
+               else{
+                   memset(desc + offset + 20, ' ', 1);
+                   offset = offset + 21;
+               }
+
+               sprintf(desc + offset, "%i", level);
+
+               strncpy(vol_label, desc, 44);
+               fprintf(stderr, "taper: added vtbl label string %i: \"%s\"\n",
+                       filenum, vol_label);
+               fflush(stderr);
+
+               /* pass label string on to tape writer */
+               syncpipe_put('L');
+               syncpipe_putint(filenum);
+               syncpipe_putstr(vol_label);             
+
+               /* 
+                * reformat datestamp for later use with set_date from vtblc 
+                */
+               strptime(datestamp, "%Y%m%d", &backup_time);
+               strftime(vol_date, 20, "%T %D", &backup_time);
+               fprintf(stderr, 
+                       "taper: reformatted vtbl date string: \"%s\"->\"%s\"\n",
+                       datestamp,
+                       vol_date);
+
+               /* pass date string on to tape writer */                
+               syncpipe_put('D');
+               syncpipe_putint(filenum);
+               syncpipe_putstr(vol_date);
+
+#endif /* HAVE_LIBVTBLC */
+           }
+           return;
+
+       default:
+           assert(0);
+       }
+    }
+}
+
+int taper_fill_buffer(fd, bp, buflen)
+int fd;
+buffer_t *bp;
+int buflen;
+{
+    char *curptr;
+    int spaceleft, cnt;
+
+    curptr = bp->buffer;
+    bp->size = 0;
+    spaceleft = buflen;
+
+    do {
+       cnt = read(fd, curptr, spaceleft);
+       switch(cnt) {
+       case 0: /* eof */
+           if(interactive) fputs("r0", stderr);
+           return bp->size;
+       case -1:        /* error on read, punt */
+           if(interactive) fputs("rE", stderr);
+           return -1;
+       default:
+           spaceleft -= cnt;
+           curptr += cnt;
+           bp->size += cnt;
+       }
+
+    } while(spaceleft > 0);
+
+    if(interactive) fputs("R", stderr);
+    return bp->size;
+}
+
+
+
+/*
+ * ========================================================================
+ * TAPE WRITER SIDE
+ *
+ */
+times_t idlewait, rdwait, wrwait, fmwait;
+long total_writes;
+double total_tape_used;
+int total_tape_fm;
+
+void write_file P((void));
+int write_buffer P((buffer_t *bp));
+
+void tape_writer_side(getp, putp)
+int getp, putp;
+{
+    char tok;
+    int tape_started;
+    char *str;
+    char *hostname;
+    char *diskname;
+    char *datestamp;
+    int level;
+
+#ifdef HAVE_LIBVTBLC
+    char *vol_label;
+    char *vol_date;
+#endif /* HAVE_LIBVTBLC */
+
+    procname = "writer";
+    syncpipe_init(getp, putp);
+
+    tape_started = 0;
+    idlewait = times_zero;
+
+    while(1) {
+       startclock();
+       tok = syncpipe_get();
+       idlewait = timesadd(idlewait, stopclock());
+       if(tok != 'S' && tok != 'Q' && !tape_started) {
+           error("writer: token '%c' before start", tok);
+       }
+
+       switch(tok) {
+       case 'S':               /* start-tape */
+           if(tape_started) {
+               error("writer: multiple start requests");
+           }
+           str = syncpipe_getstr();
+           if(!first_tape(str ? str : "bad-datestamp")) {
+               if(tape_fd >= 0) {
+                   tapefd_close(tape_fd);
+                   tape_fd = -1;
+               }
+               syncpipe_put('E');
+               syncpipe_putstr(errstr);
+               /* wait for reader to acknowledge error */
+               do {
+                   tok = syncpipe_get();
+                   if(tok != 'e') {
+                       error("writer: got '%c' unexpectedly after error", tok);
+                   }
+               } while(tok != 'e');
+           } else {
+               syncpipe_put('S');
+               tape_started = 1;
+           }
+           amfree(str);
+
+           break;
+
+       case 'O':               /* open-output */
+           datestamp = syncpipe_getstr();
+           tapefd_setinfo_datestamp(tape_fd, datestamp);
+           amfree(datestamp);
+           hostname = syncpipe_getstr();
+           tapefd_setinfo_host(tape_fd, hostname);
+           amfree(hostname);
+           diskname = syncpipe_getstr();
+           tapefd_setinfo_disk(tape_fd, diskname);
+           amfree(diskname);
+           level = syncpipe_getint();
+           tapefd_setinfo_level(tape_fd, level);
+           write_file();
+           break;
+
+#ifdef HAVE_LIBVTBLC
+       case 'L':               /* read vtbl label */
+           vtbl_no = syncpipe_getint();
+           vol_label = syncpipe_getstr();
+           fprintf(stderr, "taper: read label string \"%s\" from pipe\n", 
+                   vol_label);
+           strncpy(vtbl_entry[vtbl_no].label, vol_label, 45);
+           break;
+
+       case 'D':               /* read vtbl date */
+           vtbl_no = syncpipe_getint();
+           vol_date = syncpipe_getstr();
+           fprintf(stderr, "taper: read date string \"%s\" from pipe\n", 
+                   vol_date);
+           strncpy(vtbl_entry[vtbl_no].date, vol_date, 20);
+           break;
+#endif /* HAVE_LIBVTBLC */
+
+       case 'Q':
+           end_tape(0);        /* XXX check results of end tape ?? */
+           clear_tapelist();
+           amfree(taper_datestamp);
+           amfree(label);
+           amfree(errstr);
+           amfree(changer_resultstr);
+           amfree(tapedev);
+           amfree(config_dir);
+           amfree(config_name);
+
+           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);
+           }
+
+           exit(0);
+
+       default:
+           assert(0);
+       }
+    }
+}
+
+void write_file()
+{
+    buffer_t *bp;
+    int full_buffers, i, bufnum;
+    char tok;
+    char number[NUM_STR_SIZE];
+    char *rdwait_str, *wrwait_str, *fmwait_str;
+
+    rdwait = wrwait = times_zero;
+    total_writes = 0;
+
+    bp = buftable;
+    full_buffers = 0;
+    tok = '?';
+
+    if(bufdebug) {
+       fprintf(stderr, "taper: w: start file\n");
+       fflush(stderr);
+    }
+
+    /*
+     * Tell the reader that the tape is open, and give it all the buffers.
+     */
+    syncpipe_put('O');
+    for(i = 0; i < conf_tapebufs; i++) {
+       if(bufdebug) {
+           fprintf(stderr, "taper: w: put R%d\n", i);
+           fflush(stderr);
+       }
+       syncpipe_put('R'); syncpipe_putint(i);
+    }
+
+    /*
+     * We write the filemark at the start of the file rather than at the end,
+     * so that it can proceed in parallel with the reader's initial filling
+     * up of the buffers.
+     */
+
+    startclock();
+    if(!write_filemark())
+       goto tape_error;
+    fmwait = stopclock();
+
+    filenum += 1;
+
+    do {
+
+       /*
+        * STOPPED MODE
+        *
+        * At the start of the file, or if the input can't keep up with the
+        * tape, we enter STOPPED mode, which waits for most of the buffers
+        * to fill up before writing to tape.  This maximizes the amount of
+        * data written in chunks to the tape drive, minimizing the number
+        * of starts/stops, which in turn saves tape and time.
+        */
+
+       if(interactive) fputs("[WS]", stderr);
+       startclock();
+       while(full_buffers < conf_tapebufs - THRESHOLD) {
+           tok = syncpipe_get();
+           if(tok != 'W') break;
+           bufnum = syncpipe_getint();
+           if(bufdebug) {
+               fprintf(stderr,"taper: w: got W%d\n",bufnum);
+               fflush(stderr);
+           }
+           full_buffers++;
+       }
+       rdwait = timesadd(rdwait, stopclock());
+
+       /*
+        * STARTING MODE
+        *
+        * We start output when sufficient buffers have filled up, or at
+        * end-of-file, whichever comes first.  Here we drain all the buffers
+        * that were waited on in STOPPED mode.  If more full buffers come
+        * in, then we will be STREAMING.
+        */
+
+       while(full_buffers) {
+           if(tt_file_pad && bp->size < tt_blocksize) {
+               memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
+               bp->size = tt_blocksize;
+           }
+           if(!write_buffer(bp)) goto tape_error;
+           full_buffers--;
+           bp = nextbuf(bp);
+       }
+
+       /*
+        * STREAMING MODE
+        *
+        * With any luck, the input source is faster than the tape drive.  In
+        * this case, full buffers will appear in the circular queue faster
+        * than we can write them, so the next buffer in the queue will always
+        * be marked FULL by the time we get to it.  If so, we'll stay in
+        * STREAMING mode.
+        *
+        * On the other hand, if we catch up to the input and thus would have
+        * to wait for buffers to fill, we are then STOPPED again.
+        */
+
+       while(tok == 'W' && bp->status == FULL) {
+           tok = syncpipe_get();
+           if(tok == 'W') {
+               bufnum = syncpipe_getint();
+               if(bufdebug) {
+                   fprintf(stderr,"taper: w: got W%d\n",bufnum);
+                   fflush(stderr);
+               }
+               if(bufnum != bp-buftable) {
+                   fprintf(stderr,
+                           "taper: tape-writer: my buf %d reader buf %d\n",
+                           (int)(bp-buftable), bufnum);
+                   fflush(stderr);
+                   syncpipe_put('E');
+                   syncpipe_putstr("writer-side buffer mismatch");
+                   goto error_ack;
+               }
+               if(tt_file_pad && bp->size < tt_blocksize) {
+                   memset(bp->buffer+bp->size, 0, tt_blocksize - bp->size);
+                   bp->size = tt_blocksize;
+               }
+               if(!write_buffer(bp)) goto tape_error;
+               bp = nextbuf(bp);
+           }
+           else if(tok == 'Q')
+               return;
+           else if(tok == 'X')
+               goto reader_buffer_snafu;
+           else
+               error("writer-side not expecting token: %c", tok);
+       }
+    } while(tok == 'W');
+
+    /* got close signal from reader, acknowledge it */
+
+    if(tok == 'X')
+       goto reader_buffer_snafu;
+
+    assert(tok == 'C');
+    syncpipe_put('C');
+
+    /* tell reader the tape and file number */
+
+    syncpipe_putstr(label);
+    ap_snprintf(number, sizeof(number), "%d", filenum);
+    syncpipe_putstr(number);
+
+    ap_snprintf(number, sizeof(number), "%ld", total_writes);
+    rdwait_str = stralloc(walltime_str(rdwait));
+    wrwait_str = stralloc(walltime_str(wrwait));
+    fmwait_str = stralloc(walltime_str(fmwait));
+    errstr = newvstralloc(errstr,
+                         "{wr:",
+                         " writers ", number,
+                         " rdwait ", rdwait_str,
+                         " wrwait ", wrwait_str,
+                         " filemark ", fmwait_str,
+                         "}",
+                         NULL);
+    amfree(rdwait_str);
+    amfree(wrwait_str);
+    amfree(fmwait_str);
+    syncpipe_putstr(errstr);
+
+    /* XXX go to next tape if past tape size? */
+
+    return;
+
+ tape_error:
+    /* got tape error */
+    if(next_tape(1)) syncpipe_put('T');        /* next tape in place, try again */
+    else syncpipe_put('E');            /* no more tapes, fail */
+    syncpipe_putstr(errstr);
+
+ error_ack:
+    /* wait for reader to acknowledge error */
+    do {
+       tok = syncpipe_get();
+       if(tok != 'W' && tok != 'C' && tok != 'e')
+           error("writer: got '%c' unexpectedly after error", tok);
+       if(tok == 'W')
+           syncpipe_getint();  /* eat buffer number */
+    } while(tok != 'e');
+    return;
+
+ reader_buffer_snafu:
+    syncpipe_put('x');
+    return;
+}
+
+int write_buffer(bp)
+buffer_t *bp;
+{
+    int rc;
+
+    if(bp->status != FULL) {
+       /* XXX buffer management snafu */
+       assert(0);
+    }
+
+    startclock();
+    rc = tapefd_write(tape_fd, bp->buffer, bp->size);
+    if(rc == bp->size) {
+#if defined(NEED_RESETOFS)
+       static double tape_used_modulus_2gb = 0;
+
+       /*
+        * If the next write will go over the 2 GByte boundary, reset
+        * the kernel concept of where we are to make sure it does not
+        * go silly on us.
+        */
+       tape_used_modulus_2gb += (double)rc;
+       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;
+       bp->status = EMPTY;
+       if(interactive || bufdebug) dumpstatus(bp);
+       if(interactive) fputs("W", stderr);
+
+       if(bufdebug) {
+           fprintf(stderr, "taper: w: put R%d\n", (int)(bp-buftable));
+           fflush(stderr);
+       }
+       syncpipe_put('R'); syncpipe_putint(bp-buftable);
+       return 1;
+    } else {
+       errstr = newvstralloc(errstr,
+                             "writing file: ",
+                             (rc != -1) ? "short write" : strerror(errno),
+                             NULL);
+       wrwait = timesadd(wrwait, stopclock());
+       if(interactive) fputs("[WE]", stderr);
+       return 0;
+    }
+}
+
+
+/*
+ * ========================================================================
+ * SHARED-MEMORY BUFFER SUBSYSTEM
+ *
+ */
+
+#ifdef HAVE_SYSVSHM
+
+int shmid = -1;
+
+char *attach_buffers(size)
+    unsigned int size;
+{
+    char *result;
+
+    shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0700);
+    if(shmid == -1) {
+       return NULL;
+    }
+
+    result = (char *)shmat(shmid, (SHM_ARG_TYPE *)NULL, 0);
+
+    if(result == (char *)-1) {
+       int save_errno = errno;
+
+       destroy_buffers();
+       errno = save_errno;
+       error("shmat: %s", strerror(errno));
+    }
+
+    return result;
+}
+
+
+void detach_buffers(bufp)
+    char *bufp;
+{
+    if(shmdt((SHM_ARG_TYPE *)bufp) == -1) {
+       error("shmdt: %s", strerror(errno));
+    }
+}
+
+void destroy_buffers()
+{
+    if(shmid == -1) return;    /* nothing to destroy */
+    if(shmctl(shmid, IPC_RMID, NULL) == -1) {
+       error("shmctl: %s", strerror(errno));
+    }
+}
+
+#else
+#ifdef HAVE_MMAP
+
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#ifndef MAP_ANON
+#  ifdef MAP_ANONYMOUS                 /* OSF/1-style */
+#    define MAP_ANON MAP_ANONYMOUS
+#  else                                        /* SunOS4-style */
+#    define MAP_ANON 0
+#    define ZERO_FILE "/dev/zero"
+#  endif
+#endif
+
+int shmfd = -1;
+unsigned int saved_size;
+
+char *attach_buffers(size)
+    unsigned int size;
+{
+    char *shmbuf;
+
+#ifdef ZERO_FILE
+    shmfd = open(ZERO_FILE, O_RDWR);
+    if(shmfd == -1) {
+       error("attach_buffers: could not open %s: %s",
+             ZERO_FILE,
+             strerror(errno));
+    }
+#endif
+
+    saved_size = size;
+    shmbuf = (char *) mmap((void *) 0,
+                          size,
+                          PROT_READ|PROT_WRITE,
+                          MAP_ANON|MAP_SHARED,
+                          shmfd, 0);
+
+    return shmbuf;
+}
+
+void detach_buffers(bufp)
+char *bufp;
+{
+    if(munmap((void *)bufp, saved_size) == -1) {
+       error("detach_buffers: munmap: %s", strerror(errno));
+    }
+
+    aclose(shmfd);
+}
+
+void destroy_buffers()
+{
+}
+
+#else
+error: must define either HAVE_SYSVSHM or HAVE_MMAP!
+#endif
+#endif
+
+
+
+/*
+ * ========================================================================
+ * SYNC-PIPE SUBSYSTEM
+ *
+ */
+
+int getpipe, putpipe;
+
+void syncpipe_init(rd, wr)
+int rd, wr;
+{
+    getpipe = rd;
+    putpipe = wr;
+}
+
+char syncpipe_get()
+{
+    int rc;
+    char buf[1];
+
+    rc = read(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));
+
+    if(bufdebug && *buf != 'R' && *buf != 'W') {
+       fprintf(stderr,"taper: %c: getc %c\n",*procname,*buf);
+       fflush(stderr);
+    }
+
+    return buf[0];
+}
+
+int syncpipe_getint()
+{
+    int rc;
+    int i;
+    int len = sizeof(i);
+    char *p;
+
+    for(p = (char *)&i; len > 0; len -= rc, p += rc) {
+       if ((rc = read(getpipe, p, len)) <= 0) {
+           error("syncpipe_getint: %s",
+                 rc < 0 ? strerror(errno) : "short read");
+       }
+    }
+
+    return i;
+}
+
+
+char *syncpipe_getstr()
+{
+    int rc;
+    int len;
+    char *p;
+    char *str;
+
+    if((len = syncpipe_getint()) <= 0) {
+       return NULL;
+    }
+
+    str = alloc(len);
+
+    for(p = str; len > 0; len -= rc, p += rc) {
+       if ((rc = read(getpipe, p, len)) <= 0) {
+           error("syncpipe_getstr: %s",
+                 rc < 0 ? strerror(errno) : "short read");
+       }
+    }
+
+    return str;
+}
+
+
+void syncpipe_put(chi)
+int chi;
+{
+    int l, n, s;
+    char ch = chi;
+    char *item = &ch;
+
+    if(bufdebug && chi != 'R' && chi != 'W') {
+       fprintf(stderr,"taper: %c: putc %c\n",*procname,chi);
+       fflush(stderr);
+    }
+
+    for(l = 0, n = sizeof(ch); l < n; l += s) {
+       if((s = write(putpipe, item + l, n - l)) < 0) {
+           error("syncpipe_put: %s", strerror(errno));
+       }
+    }
+}
+
+void syncpipe_putint(i)
+int i;
+{
+    int l, n, s;
+    char *item = (char *)&i;
+
+    for(l = 0, n = sizeof(i); l < n; l += s) {
+       if((s = write(putpipe, item + l, n - l)) < 0) {
+           error("syncpipe_putint: %s", strerror(errno));
+       }
+    }
+}
+
+void syncpipe_putstr(item)
+char *item;
+{
+    int l, n, s;
+
+    n = strlen(item)+1;                                /* send '\0' as well */
+    syncpipe_putint(n);
+    for(l = 0, n = strlen(item)+1; l < n; l += s) {
+       if((s = write(putpipe, item + l, n - l)) < 0) {
+           error("syncpipe_putstr: %s", strerror(errno));
+       }
+    }
+}
+
+\f
+/*
+ * ========================================================================
+ * TAPE MANIPULATION SUBSYSTEM
+ *
+ */
+
+/* local functions */
+int scan_init P((int rc, int ns, int bk));
+int taperscan_slot P((int rc, char *slotstr, char *device));
+char *taper_scan P((void));
+int label_tape P((void));
+
+int label_tape()
+{
+    char *conf_tapelist_old = NULL;
+    char *olddatestamp = NULL;
+    char *result;
+    tape_t *tp;
+    static int first_call = 1;
+
+    if(have_changer) {
+       amfree(tapedev);
+       if ((tapedev = taper_scan()) == NULL) {
+           errstr = newstralloc(errstr, changer_resultstr);
+           return 0;
+       }
+    }
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+    if (is_zftape(tapedev) == 1){
+       if((tape_fd = tape_open(tapedev, O_RDONLY)) == -1) {
+           errstr = newstralloc2(errstr, "taper: ",
+                                 (errno == EACCES) ? "tape is write-protected"
+                                 : strerror(errno));
+           return 0;
+       }
+       if((result = tapefd_rdlabel(tape_fd, &olddatestamp, &label)) != NULL) {
+           amfree(olddatestamp);
+           errstr = newstralloc(errstr, result);
+           return 0;
+       }
+       if(tapefd_rewind(tape_fd) == -1) { 
+           return 0;
+       } 
+       tapefd_close(tape_fd);
+       tape_fd = -1;
+    }
+    else
+#endif /* !HAVE_LINUX_ZFTAPE_H */
+    if((result = tape_rdlabel(tapedev, &olddatestamp, &label)) != NULL) {
+       amfree(olddatestamp);
+       errstr = newstralloc(errstr, result);
+       return 0;
+    }
+
+    fprintf(stderr, "taper: read label `%s' date `%s'\n", label, olddatestamp);
+    fflush(stderr);
+    amfree(olddatestamp);
+
+    /* check against tape list */
+    if (strcmp(label, FAKE_LABEL) != 0) {
+       tp = lookup_tapelabel(label);
+       if(tp == NULL) {
+           errstr = newvstralloc(errstr,
+                                 "label ", label,
+               " match labelstr but it not listed in the tapelist file",
+                                 NULL);
+           return 0;
+       }
+       else if(tp != NULL && !reusable_tape(tp)) {
+           errstr = newvstralloc(errstr,
+                                 "cannot overwrite active tape ", label,
+                                 NULL);
+           return 0;
+       }
+
+       if(!match(labelstr, label)) {
+           errstr = newvstralloc(errstr,
+                                 "label ", label,
+                                 " doesn\'t match labelstr \"", labelstr, "\"",
+                                 NULL);
+           return 0;
+       }
+    }
+
+    if((tape_fd = tape_open(tapedev, O_WRONLY)) == -1) {
+       if(errno == EACCES) {
+           errstr = newstralloc(errstr,
+                                "writing label: tape is write protected");
+       } else {
+           errstr = newstralloc2(errstr,
+                                 "writing label: ", strerror(errno));
+       }
+       return 0;
+    }
+
+    tapefd_setinfo_length(tape_fd, tt->length);
+
+    tapefd_setinfo_datestamp(tape_fd, taper_datestamp);
+    tapefd_setinfo_disk(tape_fd, label);
+    result = tapefd_wrlabel(tape_fd, taper_datestamp, label, tt_blocksize);
+    if(result != NULL) {
+       errstr = newstralloc(errstr, result);
+       return 0;
+    }
+
+    fprintf(stderr, "taper: wrote label `%s' date `%s'\n", label, taper_datestamp);
+    fflush(stderr);
+
+#ifdef HAVE_LIBVTBLC
+    /* store time for the first volume entry */ 
+    time(&raw_time);
+    tape_timep = localtime(&raw_time);
+    strftime(start_datestr, 20, "%T %D", tape_timep);
+    fprintf(stderr, "taper: got vtbl start time: %s\n", start_datestr);
+    fflush(stderr);
+#endif /* HAVE_LIBVTBLC */
+
+    /* write tape list */
+
+    /* XXX add cur_tape number to tape list structure */
+    if (strcmp(label, FAKE_LABEL) != 0) {
+
+       if(cur_tape == 0) {
+           conf_tapelist_old = stralloc2(conf_tapelist, ".yesterday");
+       } else {
+           char cur_str[NUM_STR_SIZE];
+
+           ap_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)) {
+           error("could not write tapelist: %s", strerror(errno));
+       }
+       amfree(conf_tapelist_old);
+
+       remove_tapelabel(label);
+       add_tapelabel(atoi(taper_datestamp), label);
+       if(write_tapelist(conf_tapelist)) {
+           error("could not write tapelist: %s", strerror(errno));
+       }
+    }
+
+    log_add(L_START, "datestamp %s label %s tape %d",
+           taper_datestamp, 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_fm = 0;
+
+    return 1;
+}
+
+int first_tape(new_datestamp)
+char *new_datestamp;
+{
+    if((have_changer = changer_init()) < 0) {
+       error("changer initialization failed: %s", strerror(errno));
+    }
+    changer_debug = 1;
+
+    taper_datestamp = newstralloc(taper_datestamp, new_datestamp);
+
+    if(!label_tape())
+       return 0;
+
+    filenum = 0;
+    return 1;
+}
+
+int next_tape(writerror)
+int writerror;
+{
+    end_tape(writerror);
+
+    if(++cur_tape >= runtapes)
+       return 0;
+
+    if(!label_tape()) {
+       return 0;
+    }
+
+    filenum = 0;
+    return 1;
+}
+
+
+int end_tape(writerror)
+int writerror;
+{
+    char *result;
+    int rc = 0;
+
+    if(tape_fd >= 0) {
+       log_add(L_INFO, "tape %s kb %ld fm %d %s", 
+               label,
+               (long) ((total_tape_used+1023.0) / 1024.0),
+               total_tape_fm,
+               writerror? errstr : "[OK]");
+
+       fprintf(stderr, "taper: writing end marker. [%s %s kb %ld fm %d]\n",
+               label,
+               writerror? "ERR" : "OK",
+               (long) ((total_tape_used+1023.0) / 1024.0),
+               total_tape_fm);
+       fflush(stderr);
+       if(! writerror) {
+           if(! write_filemark()) {
+               rc = 1;
+               goto common_exit;
+           }
+
+           result = tapefd_wrendmark(tape_fd, taper_datestamp, tt_blocksize);
+           if(result != NULL) {
+               errstr = newstralloc(errstr, result);
+               rc = 1;
+               goto common_exit;
+           }
+       }
+    }
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+    if (tape_fd >= 0 && is_zftape(tapedev) == 1) {
+       /* rewind the tape */
+
+       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) {
+           errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
+           rc = 1;
+           goto common_exit;
+       }
+       tape_fd = -1;
+
+#ifdef HAVE_LIBVTBLC
+       /* update volume table */
+       fprintf(stderr, "taper: updating volume table ...\n");
+       fflush(stderr);
+    
+       if ((tape_fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
+           if(errno == EACCES) {
+               errstr = newstralloc(errstr,
+                                    "updating volume table: tape is write protected");
+           } else {
+               errstr = newstralloc2(errstr,
+                                     "updating volume table: ", 
+                                     strerror(errno));
+           }
+           rc = 1;
+           goto common_exit;
+       }
+       /* read volume table */
+       if ((num_volumes = read_vtbl(tape_fd, volumes, vtbl_buffer,
+                                    &first_seg, &last_seg)) == -1 ) {
+           errstr = newstralloc2(errstr,
+                                 "reading volume table: ", 
+                                 strerror(errno));
+           rc = 1;
+           goto common_exit;
+       }
+       /* set volume label and date for first entry */
+       vtbl_no = 0;
+       if(set_label(label, volumes, num_volumes, vtbl_no)){
+           errstr = newstralloc2(errstr,
+                                 "setting label for entry 1: ",
+                                 strerror(errno));
+           rc = 1;
+           goto common_exit;
+       }
+       /* date of start writing this tape */
+       if (set_date(start_datestr, volumes, num_volumes, vtbl_no)){
+           errstr = newstralloc2(errstr,
+                                 "setting date for entry 1: ", 
+                                 strerror(errno));
+           rc = 1;
+           goto common_exit;
+       }
+       /* set volume labels and dates for backup files */
+       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)){
+               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)){
+               errstr = newstralloc2(errstr,
+                                     "setting date for entry i: ",
+                                     strerror(errno));
+               rc = 1;
+               goto common_exit;
+           }
+       }
+       /* set volume label and date for last entry */
+       vtbl_no = num_volumes - 1;
+       if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
+           errstr = newstralloc2(errstr,
+                                 "setting label for last entry: ", 
+                                 strerror(errno));
+           rc = 1;
+           goto common_exit;
+       }
+       datestr = NULL; /* take current time */ 
+       if (set_date(datestr, volumes, num_volumes, vtbl_no)){
+           errstr = newstralloc2(errstr,
+                                 "setting date for last entry 1: ", 
+                                 strerror(errno));
+           rc = 1;
+           goto common_exit;
+       }
+       /* write volume table back */
+       if (write_vtbl(tape_fd, volumes, vtbl_buffer, num_volumes, first_seg,
+                      op_mode == trunc)) {
+           errstr = newstralloc2(errstr,
+                                 "writing volume table: ", 
+                                 strerror(errno));
+           rc = 1;
+           goto common_exit;
+       }  
+
+       fprintf(stderr, "taper: updating volume table: done.\n");
+       fflush(stderr);
+#endif /* HAVE_LIBVTBLC */
+    }
+#endif /* !HAVE_LINUX_ZFTAPE_H */
+
+    /* close the tape and let the OS write the final filemarks */
+
+common_exit:
+
+    if(tape_fd >= 0 && tapefd_close(tape_fd) == -1 && ! writerror) {
+       errstr = newstralloc2(errstr, "closing tape: ", strerror(errno));
+       rc = 1;
+    }
+    tape_fd = -1;
+    amfree(label);
+
+    return rc;
+}
+
+
+int write_filemark()
+{
+    if(tapefd_weof(tape_fd, 1) == -1) {
+       errstr = newstralloc2(errstr, "writing filemark: ", strerror(errno));
+       return 0;
+    }
+    total_tape_fm++;
+    return 1;
+}
+
+
+/*
+ * ========================================================================
+ * TAPE CHANGER SCAN
+ *
+ */
+int nslots, backwards, found, got_match, tapedays;
+char *first_match_label = NULL, *first_match = NULL, *found_device = NULL;
+char *searchlabel, *labelstr;
+tape_t *tp;
+
+int scan_init(rc, ns, bk)
+int rc, ns, bk;
+{
+    if(rc) {
+       fprintf(stderr, "%s: could not get changer info: %s\n",
+               get_pname(), changer_resultstr);
+       return rc;
+    }
+
+    nslots = ns;
+    backwards = bk;
+
+    return 0;
+}
+
+int taperscan_slot(rc, slotstr, device)
+     int rc;
+     char *slotstr;
+     char *device;
+{
+    char *t_errstr;
+    char *scan_datestamp = NULL;
+
+    if(rc == 2) {
+       fprintf(stderr, "%s: fatal slot %s: %s\n",
+               get_pname(), slotstr, changer_resultstr);
+       fflush(stderr);
+       return 1;
+    }
+    else if(rc == 1) {
+       fprintf(stderr, "%s: slot %s: %s\n", get_pname(),
+               slotstr, changer_resultstr);
+       fflush(stderr);
+       return 0;
+    }
+    else {
+       if((t_errstr = tape_rdlabel(device, &scan_datestamp, &label)) != NULL) {
+           amfree(scan_datestamp);
+           fprintf(stderr, "%s: slot %s: %s\n",
+                   get_pname(), slotstr, t_errstr);
+           fflush(stderr);
+       }
+       else {
+           /* got an amanda tape */
+           fprintf(stderr, "%s: slot %s: date %-8s label %s",
+                   get_pname(), slotstr, scan_datestamp, label);
+           fflush(stderr);
+           amfree(scan_datestamp);
+           if(searchlabel != NULL
+              && (strcmp(label, FAKE_LABEL) == 0
+                  || strcmp(label, searchlabel) == 0)) {
+               /* it's the one we are looking for, stop here */
+               fprintf(stderr, " (exact label match)\n");
+               fflush(stderr);
+               found_device = newstralloc(found_device, device);
+               found = 1;
+               return 1;
+           }
+           else if(!match(labelstr, label)) {
+               fprintf(stderr, " (no match)\n");
+               fflush(stderr);
+           }
+           else {
+               /* not an exact label match, but a labelstr match */
+               /* check against tape list */
+               tp = lookup_tapelabel(label);
+               if(tp == NULL) {
+                   fprintf(stderr, "(not in tapelist)\n");
+                   fflush(stderr);
+               }
+               else if(!reusable_tape(tp)) {
+                   fprintf(stderr, " (active tape)\n");
+                   fflush(stderr);
+               }
+               else if(got_match == 0 && tp->datestamp == 0) {
+                   got_match = 1;
+                   first_match = newstralloc(first_match, slotstr);
+                   first_match_label = newstralloc(first_match_label, label);
+                   fprintf(stderr, " (new tape)\n");
+                   fflush(stderr);
+                   found = 3;
+                   found_device = newstralloc(found_device, device);
+                   return 1;
+               }
+               else if(got_match) {
+                   fprintf(stderr, " (labelstr match)\n");
+                   fflush(stderr);
+               }
+               else {
+                   got_match = 1;
+                   first_match = newstralloc(first_match, slotstr);
+                   first_match_label = newstralloc(first_match_label, label);
+                   fprintf(stderr, " (first labelstr match)\n");
+                   fflush(stderr);
+                   if(!backwards || !searchlabel) {
+                       found = 2;
+                       found_device = newstralloc(found_device, device);
+                       return 1;
+                   }
+               }
+           }
+       }
+    }
+    return 0;
+}
+
+char *taper_scan()
+{
+    char *outslot = NULL;
+
+    if((tp = lookup_last_reusable_tape(0)) == NULL)
+       searchlabel = NULL;
+    else
+       searchlabel = tp->label;
+
+    found = 0;
+    got_match = 0;
+
+    if (searchlabel != NULL)
+      changer_find(scan_init, taperscan_slot, searchlabel);
+    else
+      changer_scan(scan_init, taperscan_slot);
+
+    if(found == 2 || found == 3)
+       searchlabel = first_match_label;
+    else if(!found && got_match) {
+       searchlabel = first_match_label;
+       amfree(found_device);
+       if(changer_loadslot(first_match, &outslot, &found_device) == 0) {
+           found = 1;
+       }
+       amfree(outslot);
+    }
+    else if(!found) {
+       if(searchlabel) {
+           changer_resultstr = newvstralloc(changer_resultstr,
+                                            "label ", searchlabel,
+                                            " or new tape not found in rack",
+                                            NULL);
+       } else {
+           changer_resultstr = newstralloc(changer_resultstr,
+                                           "new tape not found in rack");
+       }
+    }
+
+    if(found) {
+       outslot = found_device;
+       found_device = NULL;            /* forget about our copy */
+    } else {
+       outslot = NULL;
+       amfree(found_device);
+    }
+    return outslot;
+}
diff --git a/tape-src/Makefile.am b/tape-src/Makefile.am
new file mode 100644 (file)
index 0000000..6b78e02
--- /dev/null
@@ -0,0 +1,78 @@
+# Makefile for Amanda tape library.
+
+INCLUDES =             -I$(top_srcdir)/common-src
+
+lib_LTLIBRARIES =      libamtape.la
+LIB_EXTENSION = la
+
+sbin_PROGRAMS=          ammt amdd amtapetype
+
+libamtape_la_SOURCES =         output-file.c \
+                       output-null.c \
+                       output-rait.c \
+                       output-tape.c \
+                       tapeio.c
+
+libamtape_la_LDFLAGS =  -release $(VERSION)
+
+###
+# 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) \
+       libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+# used for testing only
+
+TEST_PROGS =           amtapeio
+
+EXTRA_PROGRAMS =       $(TEST_PROGS)
+
+CLEANFILES = *.test.c
+
+amtapetype_SOURCES = tapetype.c
+
+noinst_HEADERS =       \
+                       output-file.h \
+                       output-null.h \
+                       output-rait.h \
+                       output-tape.h \
+                       tapeio.h
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS) $(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
+
+amtapeio_SOURCES = amtapeio.test.c
+amtapeio_LDADD =       ../common-src/libamanda.$(LIB_EXTENSION) \
+                       libamtape.$(LIB_EXTENSION) \
+                       ../common-src/libamanda.$(LIB_EXTENSION)
+
+amtapeio.test.c: $(srcdir)/tapeio.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
+
+tapetype:
+       @echo "Use amtapetype instead"
diff --git a/tape-src/Makefile.in b/tape-src/Makefile.in
new file mode 100644 (file)
index 0000000..8018cee
--- /dev/null
@@ -0,0 +1,701 @@
+# Makefile.in generated by automake 1.8.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  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 tape library.
+
+
+
+SOURCES = $(libamtape_la_SOURCES) amdd.c ammt.c $(amtapeio_SOURCES) $(amtapetype_SOURCES)
+
+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 = :
+host_triplet = @host@
+sbin_PROGRAMS = ammt$(EXEEXT) amdd$(EXEEXT) amtapetype$(EXEEXT)
+EXTRA_PROGRAMS = $(am__EXEEXT_1)
+subdir = tape-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__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(sbindir)"
+libLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libamtape_la_LIBADD =
+am_libamtape_la_OBJECTS = output-file.lo output-null.lo output-rait.lo \
+       output-tape.lo tapeio.lo
+libamtape_la_OBJECTS = $(am_libamtape_la_OBJECTS)
+am__EXEEXT_1 = amtapeio$(EXEEXT)
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(sbin_PROGRAMS)
+amdd_SOURCES = amdd.c
+amdd_OBJECTS = amdd.$(OBJEXT)
+amdd_LDADD = $(LDADD)
+amdd_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+ammt_SOURCES = ammt.c
+ammt_OBJECTS = ammt.$(OBJEXT)
+ammt_LDADD = $(LDADD)
+ammt_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_amtapeio_OBJECTS = amtapeio.test.$(OBJEXT)
+amtapeio_OBJECTS = $(am_amtapeio_OBJECTS)
+amtapeio_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+am_amtapetype_OBJECTS = tapetype.$(OBJEXT)
+amtapetype_OBJECTS = $(am_amtapetype_OBJECTS)
+amtapetype_LDADD = $(LDADD)
+amtapetype_DEPENDENCIES = ../common-src/libamanda.$(LIB_EXTENSION) \
+       libamtape.$(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
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/amdd.Po ./$(DEPDIR)/ammt.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/amtapeio.test.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/output-file.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/output-null.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/output-rait.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/output-tape.Plo ./$(DEPDIR)/tapeio.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/tapetype.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libamtape_la_SOURCES) amdd.c ammt.c $(amtapeio_SOURCES) \
+       $(amtapetype_SOURCES)
+DIST_SOURCES = $(libamtape_la_SOURCES) amdd.c ammt.c \
+       $(amtapeio_SOURCES) $(amtapetype_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@
+AMPLOT_CAT_COMPRESS = @AMPLOT_CAT_COMPRESS@
+AMPLOT_CAT_GZIP = @AMPLOT_CAT_GZIP@
+AMPLOT_CAT_PACK = @AMPLOT_CAT_PACK@
+AMPLOT_COMPRESS = @AMPLOT_COMPRESS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+AWK_VAR_ASSIGNMENT_OPT = @AWK_VAR_ASSIGNMENT_OPT@
+BINARY_OWNER = @BINARY_OWNER@
+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@
+DUMP = @DUMP@
+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_DIRX = @GNUTAR_LISTED_INCREMENTAL_DIRX@
+GREP = @GREP@
+GZIP = @GZIP@
+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@
+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_TAPE_FALSE = @WANT_TAPE_FALSE@
+WANT_TAPE_TRUE = @WANT_TAPE_TRUE@
+XFSDUMP = @XFSDUMP@
+XFSRESTORE = @XFSRESTORE@
+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@
+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_srcdir)/common-src
+lib_LTLIBRARIES = libamtape.la
+LIB_EXTENSION = la
+libamtape_la_SOURCES = output-file.c \
+                       output-null.c \
+                       output-rait.c \
+                       output-tape.c \
+                       tapeio.c
+
+libamtape_la_LDFLAGS = -release $(VERSION)
+
+###
+# 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) \
+       libamtape.$(LIB_EXTENSION) \
+       ../common-src/libamanda.$(LIB_EXTENSION)
+
+
+# used for testing only
+TEST_PROGS = amtapeio
+CLEANFILES = *.test.c
+amtapetype_SOURCES = tapetype.c
+noinst_HEADERS = \
+                       output-file.h \
+                       output-null.h \
+                       output-rait.h \
+                       output-tape.h \
+                       tapeio.h
+
+amtapeio_SOURCES = amtapeio.test.c
+amtapeio_LDADD = ../common-src/libamanda.$(LIB_EXTENSION) \
+                       libamtape.$(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  tape-src/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  tape-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="`echo $$p | sed -e 's|^.*/||'`"; \
+           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)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         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
+libamtape.la: $(libamtape_la_OBJECTS) $(libamtape_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(libamtape_la_LDFLAGS) $(libamtape_la_OBJECTS) $(libamtape_la_LIBADD) $(LIBS)
+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
+amdd$(EXEEXT): $(amdd_OBJECTS) $(amdd_DEPENDENCIES) 
+       @rm -f amdd$(EXEEXT)
+       $(LINK) $(amdd_LDFLAGS) $(amdd_OBJECTS) $(amdd_LDADD) $(LIBS)
+ammt$(EXEEXT): $(ammt_OBJECTS) $(ammt_DEPENDENCIES) 
+       @rm -f ammt$(EXEEXT)
+       $(LINK) $(ammt_LDFLAGS) $(ammt_OBJECTS) $(ammt_LDADD) $(LIBS)
+amtapeio$(EXEEXT): $(amtapeio_OBJECTS) $(amtapeio_DEPENDENCIES) 
+       @rm -f amtapeio$(EXEEXT)
+       $(LINK) $(amtapeio_LDFLAGS) $(amtapeio_OBJECTS) $(amtapeio_LDADD) $(LIBS)
+amtapetype$(EXEEXT): $(amtapetype_OBJECTS) $(amtapetype_DEPENDENCIES) 
+       @rm -f amtapetype$(EXEEXT)
+       $(LINK) $(amtapetype_LDFLAGS) $(amtapetype_OBJECTS) $(amtapetype_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amdd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ammt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amtapeio.test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output-file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output-null.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output-rait.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output-tape.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tapeio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tapetype.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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(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 -z "$$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)$(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:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -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-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-libLTLIBRARIES 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-libLTLIBRARIES \
+       uninstall-sbinPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libLTLIBRARIES 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-info \
+       install-info-am install-libLTLIBRARIES 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-libLTLIBRARIES uninstall-sbinPROGRAMS
+
+
+install-exec-hook:
+       @list="$(sbin_PROGRAMS) $(sbin_SCRIPTS)"; \
+       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; \
+       done
+       @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
+
+amtapeio.test.c: $(srcdir)/tapeio.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
+
+%.test.c: $(srcdir)/%.c
+       echo '#define TEST' >$@
+       echo '#include "$<"' >>$@
+
+tapetype:
+       @echo "Use amtapetype instead"
+# 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/tape-src/amdd.c b/tape-src/amdd.c
new file mode 100644 (file)
index 0000000..3f21b11
--- /dev/null
@@ -0,0 +1,228 @@
+#ifdef NO_AMANDA
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "output-rait.h"
+
+#define        tape_open       rait_open
+#define        tapefd_read     rait_read
+#define        tapefd_write    rait_write
+#define tapefd_setinfo_length(outfd, length)
+#define        tapefd_close    rait_close
+
+#else
+#include "amanda.h"
+#include "tapeio.h"
+#endif
+
+extern int optind;
+
+static int debug_amdd = 0;
+static char *pgm = NULL;
+
+static void
+usage()
+{
+    fprintf(stderr, "usage: %s ", pgm);
+    fprintf(stderr, " [-d]");
+    fprintf(stderr, " [-l length]");
+    fprintf(stderr, " [if=input]");
+    fprintf(stderr, " [of=output]");
+    fprintf(stderr, " [bs=blocksize]");
+    fprintf(stderr, " [count=count]");
+    fprintf(stderr, " [skip=count]");
+    fprintf(stderr, "\n");
+    exit(1);
+}
+
+int
+main(int argc, char **argv) {
+    int infd = 0;                              /* stdin */
+    int outfd = 1;                             /* stdout */
+    int blocksize = 512;
+    int skip=0;
+    int len;
+    int pread, fread, pwrite, fwrite;
+    int res = 0;
+    char *buf;
+    int count = 0;
+    int have_count = 0;
+    int save_errno;
+    int ch;
+    char *eq;
+    int length = 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++;
+    } else {
+       pgm = argv[0];
+    }
+    while(-1 != (ch = getopt(argc, argv, "hdl:"))) {
+       switch(ch) {
+       case 'd':
+           debug_amdd = 1;
+           fprintf(stderr, "debug mode!\n");
+           break;
+       case 'l':
+           have_length = 1;
+           length = atoi(optarg);
+           len = 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;
+               }
+           } else {
+               length /= 1024;
+           }
+           break;
+       case 'h':
+       default:
+           usage();
+           /* NOTREACHED */
+       }
+    }
+
+    read_func = read;
+    write_func = write;
+    for( ; optind < argc; optind++) {
+       if(0 == (eq = strchr(argv[optind], '='))) {
+           usage();
+           /* NOTREACHED */
+       }
+       len = eq - argv[optind];
+       if(0 == strncmp("if", argv[optind], len)) {
+           if((infd = tape_open(eq + 1, O_RDONLY)) < 0) {
+               save_errno = errno;
+               fprintf(stderr, "%s: %s: ", pgm, eq + 1);
+               errno = save_errno;
+               perror("open");
+               return 1;
+           }
+           read_func = tapefd_read;
+            if(debug_amdd) {
+               fprintf(stderr, "input opened \"%s\", got fd %d\n",
+                               eq + 1, infd);
+           }
+       } else if(0 == strncmp("of", argv[optind], 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);
+               errno = save_errno;
+               perror("open");
+               return 1;
+           }
+           write_func = tapefd_write;
+            if(debug_amdd) {
+               fprintf(stderr, "output opened \"%s\", got fd %d\n",
+                               eq + 1, outfd);
+           }
+           if(have_length) {
+               if(debug_amdd) {
+                   fprintf(stderr, "length set to %d\n", length);
+               }
+               tapefd_setinfo_length(outfd, length);
+           }
+       } else if(0 == strncmp("bs", argv[optind], len)) {
+           blocksize = atoi(eq + 1);
+           len = strlen(argv[optind]);
+           if(len > 0) {
+               switch(argv[optind][len-1] ) {
+               case 'k': blocksize *= 1024;            break;
+               case 'b': blocksize *= 512;             break;
+               case 'M': blocksize *= 1024 * 1024;     break;
+               }
+           }
+           if(debug_amdd) {
+               fprintf(stderr, "blocksize set to %d\n", blocksize);
+           }
+       } else if(0 == strncmp("count", argv[optind], len)) {
+           count = atoi(eq + 1);
+           have_count = 1;
+           if(debug_amdd) {
+               fprintf(stderr, "count set to %d\n", count);
+           }
+       } else if(0 == strncmp("skip", argv[optind], len)) {
+           skip = atoi(eq + 1);
+           if(debug_amdd) {
+               fprintf(stderr, "skip set to %d\n", skip);
+           }
+       } else {
+           fprintf(stderr, "%s: bad argument: \"%s\"\n", pgm, argv[optind]);
+           return 1;
+       }
+    }
+
+    if(0 == (buf = malloc(blocksize))) {
+       save_errno = errno;
+       fprintf(stderr, "%s: ", pgm);
+       errno = save_errno;
+       perror("malloc error");
+       return 1;
+    }
+
+    eq = "read error";
+    pread = fread = pwrite = fwrite = 0;
+    while(0 < (len = (*read_func)(infd, buf, blocksize))) {
+       if(skip-- > 0) {
+           continue;
+       }
+       if(len == blocksize) {
+           fread++;
+       } else if(len > 0) {
+           pread++;
+       }
+       len = (*write_func)(outfd, buf, len);
+       if(len < 0) {
+           eq = "write error";
+           break;
+       } else if(len == blocksize) {
+           fwrite++;
+       } else if(len > 0) {
+           pwrite++;
+       }
+       if(have_count) {
+           if(--count <= 0) {
+               len = 0;
+               break;
+           }
+       }
+    }
+    if(len < 0) {
+       save_errno = errno;
+       fprintf(stderr, "%s: ", pgm);
+       errno = save_errno;
+       perror(eq);
+       res = 1;
+    }
+    fprintf(stderr, "%d+%d in\n%d+%d out\n", fread, pread, fwrite, pwrite);
+    if(read_func == tapefd_read) {
+       if(0 != tapefd_close(infd)) {
+           save_errno = errno;
+           fprintf(stderr, "%s: ", pgm);
+           errno = save_errno;
+           perror("input close");
+           res = 1;
+       }
+    }
+    if(write_func == tapefd_write) {
+       if(0 != tapefd_close(outfd)) {
+           save_errno = errno;
+           fprintf(stderr, "%s: ", pgm);
+           errno = save_errno;
+           perror("output close");
+           res = 1;
+       }
+    }
+    return res;
+}
diff --git a/tape-src/ammt.c b/tape-src/ammt.c
new file mode 100644 (file)
index 0000000..ca5e1c9
--- /dev/null
@@ -0,0 +1,272 @@
+#ifdef NO_AMANDA
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "output-rait.h"
+
+extern char *getenv();
+
+#define        tape_open       rait_open
+#define        tapefd_read     rait_read
+#define        tapefd_write    rait_write
+#define        tapefd_fsf      rait_tapefd_fsf
+#define        tapefd_rewind   rait_tapefd_rewind
+#define        tapefd_status   rait_tapefd_status
+#define        tapefd_unload   rait_tapefd_unload
+#define        tapefd_weof     rait_tapefd_weof
+#define tapefd_setinfo_length(outfd, length)
+#define        tapefd_close    rait_close
+
+#else
+#include "amanda.h"
+#include "tapeio.h"
+#endif
+
+extern int optind;
+
+static int do_asf();
+static int do_bsf();
+static int do_status();
+
+struct cmd {
+    char *name;
+    int min_chars;
+    int count;
+    int (*func)();
+    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 }
+};
+
+static char *pgm;
+static int debug_ammt = 0;
+
+static char *tapename;
+
+static int
+do_asf(fd, count)
+    int fd;
+    int count;
+{
+    int r;
+
+    if(debug_ammt) {
+       fprintf(stderr, "calling tapefd_rewind()\n");
+    }
+    if(0 != (r = tapefd_rewind(fd))) {
+       return r;
+    }
+    if(debug_ammt) {
+       fprintf(stderr, "calling tapefd_fsf(%d)\n", count);
+    }
+    return tapefd_fsf(fd, count);
+}
+
+static int
+do_bsf(fd, count)
+    int fd;
+    int count;
+{
+    if(debug_ammt) {
+       fprintf(stderr, "calling tapefd_fsf(%d)\n", -count);
+    }
+    return tapefd_fsf(fd, -count);
+}
+
+static int
+do_status(fd, count)
+    int fd;
+    int count;
+{
+    int ret;
+    struct am_mt_status stat;
+
+    if(debug_ammt) {
+       fprintf(stderr, "calling tapefd_status()\n");
+    }
+    if((ret = tapefd_status(fd, &stat)) != 0) {
+       return ret;
+    }
+    printf("%s status:", tapename);
+    if(stat.online_valid) {
+       if(stat.online) {
+           fputs(" ONLINE", stdout);
+       } else {
+           fputs(" OFFLINE", stdout);
+       }
+    }
+    if(stat.bot_valid && stat.bot) {
+       fputs(" BOT", stdout);
+    }
+    if(stat.eot_valid && stat.eot) {
+       fputs(" EOT", stdout);
+    }
+    if(stat.protected_valid && stat.protected) {
+       fputs(" PROTECTED", stdout);
+    }
+    if(stat.device_status_valid) {
+       printf(" ds == 0x%0*lx",
+              stat.device_status_size * 2,
+              (unsigned long)stat.device_status);
+    }
+    if(stat.error_status_valid) {
+       printf(" er == 0x%0*lx",
+              stat.error_status_size * 2,
+              (unsigned long)stat.error_status);
+    }
+    if(stat.fileno_valid) {
+       printf(" fileno == %ld", stat.fileno);
+    }
+    if(stat.blkno_valid) {
+       printf(" blkno == %ld", stat.blkno);
+    }
+
+    putchar('\n');
+    return 0;
+}
+
+static void
+usage()
+{
+    fprintf(stderr, "usage: %s [-d] [-f|-t device] command [count]\n", pgm);
+    exit(1);
+}
+
+int
+main(int argc, char **argv) {
+    int ch;
+    int count;
+    int i;
+    int j;
+    int fd;
+    int save_errno;
+    char *s;
+
+    if((pgm = strrchr(argv[0], '/')) != NULL) {
+       pgm++;
+    } else {
+       pgm = argv[0];
+    }
+    tapename = getenv("TAPE");
+    while(-1 != (ch = getopt(argc, argv, "df:t:"))) {
+       switch(ch) {
+       case 'd':
+           debug_ammt = 1;
+           fprintf(stderr, "debug mode!\n");
+           break;
+       case 'f':
+       case 't':
+           tapename = stralloc(optarg);
+           break;
+       default:
+           usage();
+           /* NOTREACHED */
+       }
+    }
+    if(optind >= argc) {
+       usage();
+       /* NOTREACHED */
+    }
+
+    /*
+     * Compute the minimum abbreviation for each command.
+     */
+    for(i = 0; cmd[i].name; i++) {
+       cmd[i].min_chars = 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)) {
+                   break;
+               }
+           }
+           if(0 == cmd[j].name) {
+               break;
+           }
+           cmd[i].min_chars++;
+       }
+       if(debug_ammt) {
+           fprintf(stderr, "syntax: %-20s -> %*.*s\n",
+                           cmd[i].name,
+                           cmd[i].min_chars,
+                           cmd[i].min_chars,
+                           cmd[i].name);
+       }
+    }
+
+    /*
+     * Process the command.
+     */
+    s = "unknown";
+    j = strlen(argv[optind]);
+    for(i = 0; cmd[i].name; i++) {
+       if(0 == strncmp(cmd[i].name, argv[optind], j)) {
+           if(j >= cmd[i].min_chars) {
+               break;
+           }
+           s = "ambiguous";
+       }
+    }
+    if(0 == cmd[i].name) {
+       fprintf(stderr, "%s: %s command: %s\n", pgm, s, argv[optind]);
+       exit(1);
+    }
+    optind++;
+    if(0 == tapename) {
+       fprintf(stderr, "%s: -f device or -t device is required\n", pgm);
+       exit(1);
+    }
+    if(debug_ammt) {
+       fprintf(stderr, "tapename is \"%s\"\n", tapename);
+    }
+
+    count = 1;
+    if(optind < argc && cmd[i].count) {
+       count = 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) {
+       goto report_error;
+    }
+
+    if(debug_ammt) {
+       fprintf(stderr, "processing %s(%d)\n", cmd[i].name, count);
+    }
+    if(0 != (*cmd[i].func)(fd, count)) {
+       goto report_error;
+    }
+
+    (void)tapefd_close(fd);
+
+    exit(0);
+
+report_error:
+
+    save_errno = errno;
+    fprintf(stderr, "%s %s", tapename, cmd[i].name);
+    if(cmd[i].count) {
+       fprintf(stderr, " %d", count);
+    }
+    errno = save_errno;
+    perror(" failed");
+    exit(1);
+}
diff --git a/tape-src/output-file.c b/tape-src/output-file.c
new file mode 100644 (file)
index 0000000..bbffaa9
--- /dev/null
@@ -0,0 +1,1226 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+
+/*
+ * $Id: output-file.c,v 1.1.2.4.2.4 2003/05/29 20:13:53 martinea Exp $
+ *
+ * tapeio.c virtual tape interface for a file device.
+ *
+ * The following was based on testing with real tapes on Solaris 2.6.
+ * It is possible other OS drivers behave somewhat different in end
+ * cases, usually involving errors.
+ */
+
+#include "amanda.h"
+
+#include "token.h"
+#include "tapeio.h"
+#include "output-file.h"
+#include "fileheader.h"
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#define        MAX_TOKENS              10
+
+#define        DATA_INDICATOR          "."
+#define        RECORD_INDICATOR        "-"
+
+static
+struct volume_info {
+    char *basename;                    /* filename from open */
+    struct file_info *fi;              /* file info array */
+    int 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 */
+    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 */
+} *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 */
+    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 */ 
+};
+
+static int open_count = 0;
+
+/*
+ * "Open" the tape by scanning the "data" directory.  "Tape files"
+ * have five leading digits indicating the position (counting from zero)
+ * followed by a '.' and optional other information (e.g. host/disk/level
+ * image name).
+ *
+ * We allow for the following situations:
+ *
+ *   + If we see the same "file" (position number) more than once, the
+ *     last one seen wins.  This should not normally happen.
+ *
+ *   + We allow gaps in the positions.  This should not normally happen.
+ *
+ * Anything in the directory that does not match a "tape file" name
+ * pattern is ignored.
+ *
+ * If the data directory does not exist, the "tape" is considered offline.
+ * It is allowed to "appear" later.
+ */
+
+static int
+check_online(fd)
+    int fd;
+{
+    char *token[MAX_TOKENS];
+    DIR *tapedir;
+    struct dirent *entry;
+    struct file_info *fi;
+    char *line;
+    int f;
+    int pos;
+    int rc = 0;
+
+    /*
+     * If we are already online, there is nothing else to do.
+     */
+    if (volume_info[fd].is_online) {
+       goto common_exit;
+    }
+
+    if ((tapedir = opendir(volume_info[fd].basename)) == NULL) {
+       /*
+        * We have already opened the info file which is in the same
+        * directory as the data directory, so ENOENT has to mean the data
+        * directory is not there, which we treat as being "offline".
+        * We're already offline at this point (see the above test)
+        * and this is not an error, so just return success (no error).
+        */
+
+       rc = (errno != ENOENT);
+       fprintf(stderr,"ERROR: %s: %s\n", volume_info[fd].basename, strerror(errno));
+       goto common_exit;
+    }
+    while ((entry = readdir(tapedir)) != NULL) {
+       if (is_dot_or_dotdot(entry->d_name)) {
+           continue;
+       }
+       if (isdigit((int)entry->d_name[0])
+           && isdigit((int)entry->d_name[1])
+           && isdigit((int)entry->d_name[2])
+           && isdigit((int)entry->d_name[3])
+           && isdigit((int)entry->d_name[4])
+           && entry->d_name[5] == '.') {
+
+           /*
+            * This is a "tape file".
+            */
+           pos = atoi(entry->d_name);
+           amtable_alloc((void **)&volume_info[fd].fi,
+                         &volume_info[fd].fi_limit,
+                         sizeof(*volume_info[fd].fi),
+                         pos + 1,
+                         10,
+                         NULL);
+           fi = &volume_info[fd].fi[pos];
+           if (fi->name != NULL) {
+               /*
+                * Two files with the same position???
+                */
+               amfree(fi->name);
+               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;
+           }
+       }
+    }
+    closedir(tapedir);
+
+    /*
+     * Parse the info file.  We know we are at beginning of file because
+     * the only thing that can happen to it prior to here is it being
+     * opened.
+     */
+    for (; (line = areads(fd)) != NULL; free(line)) {
+       f = split(line, token, 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;
+       }
+    }
+
+    /*
+     * Set EOM and make sure we are not pre-BOI.
+     */
+    if (volume_info[fd].file_current >= volume_info[fd].file_count) {
+       volume_info[fd].at_eom = 1;
+    }
+    if (volume_info[fd].file_current < 0) {
+       volume_info[fd].file_current = 0;
+       volume_info[fd].record_current = 0;
+    }
+
+    volume_info[fd].is_online = 1;
+
+common_exit:
+
+    return rc;
+}
+
+/*
+ * Open the tape file if not already.  If we are beyond the file count
+ * (end of tape) or the file is missing and we are only reading, set
+ * up to read /dev/null which will look like EOF.  If we are writing,
+ * create the file.
+ */
+
+static int
+file_open(fd)
+    int fd;
+{
+    struct file_info *fi;
+    char *datafilename = NULL;
+    char *recordfilename = NULL;
+    char *f = NULL;
+    int pos;
+    char *host;
+    char *disk;
+    int level;
+    char number[NUM_STR_SIZE];
+    int flags;
+    int rfd;
+    int n;
+    char *line = NULL;
+    struct record_info *ri;
+    int start_record;
+    int end_record;
+    int record_size;
+
+    if (volume_info[fd].fd < 0) {
+       flags = volume_info[fd].flags;
+       pos = volume_info[fd].file_current;
+       amtable_alloc((void **)&volume_info[fd].fi,
+                     &volume_info[fd].fi_limit,
+                     sizeof(*volume_info[fd].fi),
+                     pos + 1,
+                     10,
+                     NULL);
+       fi = &volume_info[fd].fi[pos];
+
+       /*
+        * See if we are creating a new file.
+        */
+       if (pos >= volume_info[fd].file_count) {
+           volume_info[fd].file_count = pos + 1;
+       }
+
+       /*
+        * Generate the file name to open.
+        */
+       if (fi->name == NULL) {
+           if ((volume_info[fd].flags & 3) != O_RDONLY) {
+
+               /*
+                * This is a new file, so make sure we create/truncate
+                * it.  Generate the name based on the host/disk/level
+                * information from the caller, if available, else
+                * a constant.
+                */
+               flags |= (O_CREAT | O_TRUNC);
+               host = tapefd_getinfo_host(fd);
+               disk = tapefd_getinfo_disk(fd);
+               level = tapefd_getinfo_level(fd);
+               ap_snprintf(number, sizeof(number), "%d", level);
+               if (host != NULL) {
+                   f = stralloc(host);
+               }
+               if (disk != NULL) {
+                   disk = sanitise_filename(disk);
+                   if (f == NULL) {
+                       f = stralloc(disk);
+                   } else {
+                       f = newvstralloc(f, f, ".", disk, NULL);
+                   }
+                   amfree(disk);
+               }
+               if (level >= 0) {
+                   if (f == NULL) {
+                       f = stralloc(number);
+                   } else {
+                       f = newvstralloc(f, f, ".", number, NULL);
+                   }
+               }
+               if (f == NULL) {
+                   f = stralloc("unknown");
+               }
+               amfree(fi->name);
+               fi->name = stralloc(f);
+               fi->ri_count = 0;
+               amfree(f);
+           } else {
+
+               /*
+                * This is a missing file, so set up to read nothing.
+                */
+               datafilename = stralloc("/dev/null");
+               recordfilename = stralloc("/dev/null");
+           }
+       }
+       if (datafilename == NULL) {
+           ap_snprintf(number, sizeof(number), "%05d", pos);
+           datafilename = vstralloc(volume_info[fd].basename,
+                                    number,
+                                    DATA_INDICATOR,
+                                    volume_info[fd].fi[pos].name,
+                                    NULL);
+           recordfilename = vstralloc(volume_info[fd].basename,
+                                      number,
+                                      RECORD_INDICATOR,
+                                      volume_info[fd].fi[pos].name,
+                                      NULL);
+       }
+
+       /*
+        * Do the data file open.
+        */
+       volume_info[fd].fd = open(datafilename, flags, volume_info[fd].mask);
+       amfree(datafilename);
+
+       /*
+        * Load the record information.
+        */
+       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);
+               if (n == 3) {
+                   amtable_alloc((void **)&fi->ri,
+                                 &fi->ri_limit,
+                                 sizeof(*fi->ri),
+                                 fi->ri_count + 1,
+                                 10,
+                                 NULL);
+                   ri = &fi->ri[fi->ri_count];
+                   ri->start_record = start_record;
+                   ri->end_record = end_record;
+                   ri->record_size = record_size;
+                   fi->ri_count++;
+               }
+           }
+           aclose(rfd);
+       }
+       amfree(recordfilename);
+    }
+    return volume_info[fd].fd;
+}
+
+/*
+ * Close the current data file, if open.  Dump the record information
+ * if it has been altered.
+ */
+
+static void
+file_close(fd)
+    int fd;
+{
+    struct file_info *fi;
+    int pos;
+    char number[NUM_STR_SIZE];
+    char *filename = NULL;
+    int r;
+    FILE *f;
+
+    aclose(volume_info[fd].fd);
+    pos = volume_info[fd].file_current;
+    amtable_alloc((void **)&volume_info[fd].fi,
+                 &volume_info[fd].fi_limit,
+                 sizeof(*volume_info[fd].fi),
+                 pos + 1,
+                 10,
+                 NULL);
+    fi = &volume_info[fd].fi[pos];
+    if (fi->ri_altered) {
+       ap_snprintf(number, sizeof(number), "%05d", pos);
+       filename = vstralloc(volume_info[fd].basename,
+                            number,
+                            RECORD_INDICATOR,
+                            fi->name,
+                            NULL);
+       if ((f = fopen(filename, "w")) == NULL) {
+           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);
+       }
+       afclose(f);
+       fi->ri_altered = 0;
+    }
+
+common_exit:
+
+    amfree(filename);
+}
+
+/*
+ * Release any files beyond a given position current position and reset
+ * file_count to file_current to indicate EOM.
+ */
+
+static void
+file_release(fd)
+    int fd;
+{
+    int position;
+    char *filename;
+    int pos;
+    char number[NUM_STR_SIZE];
+
+    /*
+     * If the current file is open, release everything beyond it.
+     * If it is not open, release everything from current.
+     */
+    if (volume_info[fd].fd >= 0) {
+       position = volume_info[fd].file_current + 1;
+    } else {
+       position = volume_info[fd].file_current;
+    }
+    for (pos = position; pos < volume_info[fd].file_count; pos++) {
+       amtable_alloc((void **)&volume_info[fd].fi,
+                     &volume_info[fd].fi_limit,
+                     sizeof(*volume_info[fd].fi),
+                     pos + 1,
+                     10,
+                     NULL);
+       if (volume_info[fd].fi[pos].name != NULL) {
+           ap_snprintf(number, sizeof(number), "%05d", pos);
+           filename = vstralloc(volume_info[fd].basename,
+                                number,
+                                DATA_INDICATOR,
+                                volume_info[fd].fi[pos].name,
+                                NULL);
+           unlink(filename);
+           amfree(filename);
+           filename = vstralloc(volume_info[fd].basename,
+                                number,
+                                RECORD_INDICATOR,
+                                volume_info[fd].fi[pos].name,
+                                NULL);
+           unlink(filename);
+           amfree(filename);
+           amfree(volume_info[fd].fi[pos].name);
+           volume_info[fd].fi[pos].ri_count = 0;
+       }
+    }
+    volume_info[fd].file_count = position;
+}
+
+/*
+ * Get the size of a particular record.  We assume the record information is
+ * sorted, does not overlap and does not have gaps.
+ */
+
+static int
+get_record_size(fi, record)
+    struct file_info *fi;
+    int record;
+{
+    int r;
+    struct record_info *ri;
+
+    for(r = 0; r < fi->ri_count; r++) {
+       ri = &fi->ri[r];
+       if (record <= ri->end_record) {
+           return ri->record_size;
+       }
+    }
+
+    /*
+     * For historical reasons, the default record size is 32 KBytes.
+     * This allows us to read files written by Amanda with that block
+     * size before the record information was being kept.
+     */
+    return 32 * 1024;
+}
+
+/*
+ * Update the record information.  We assume the record information is
+ * sorted, does not overlap and does not have gaps.
+ */
+
+static void
+put_record_size(fi, record, size)
+    struct file_info *fi;
+    int record;
+    int size;
+{
+    int r;
+    struct record_info *ri;
+
+    fi->ri_altered = 1;
+    if (record == 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 this record is the same size as the rest of the records
+            * in this entry, or it would replace the entire entry,
+            * reset the end record number and size, then zap the chain
+            * beyond this point.
+            */
+           if (record == ri->start_record || ri->record_size == size) {
+               ri->end_record = record;
+               ri->record_size = size;
+               fi->ri_count = r + 1;
+               return;
+           }
+           /*
+            * This record needs a new entry right after the current one.
+            */
+           ri->end_record = record - 1;
+           fi->ri_count = r + 1;
+           break;
+       }
+    }
+    /*
+     * Add a new entry.
+     */
+    amtable_alloc((void **)&fi->ri,
+                 &fi->ri_limit,
+                 sizeof(*fi->ri),
+                 fi->ri_count + 1,
+                 10,
+                 NULL);
+    ri = &fi->ri[fi->ri_count];
+    ri->start_record = record;
+    ri->end_record = record;
+    ri->record_size = size;
+    fi->ri_count++;
+}
+
+/*
+ * The normal interface routines ...
+ */
+
+int
+file_tape_open(filename, flags, mask)
+    char *filename;
+    int flags;
+    int mask;
+{
+    int fd = -1;
+    int save_errno;
+    char *info_file = NULL;
+
+    /*
+     * Use only O_RDONLY and O_RDWR.
+     */
+    if ((flags & 3) != O_RDONLY) {
+       flags &= ~3;
+       flags |= O_RDWR;
+    }
+
+    /*
+     * If the caller did not set O_CREAT (and thus, pass a mask
+     * parameter), we may still end up creating data files and need a
+     * "reasonable" value.  Pick a "tight" value on the "better safe
+     * than sorry" theory.
+     */
+    if ((flags & O_CREAT) == 0) {
+       mask = 0600;
+    }
+
+    /*
+     * Open/create the info file for this "tape".
+     */
+    info_file = stralloc2(filename, "/info");
+    if ((fd = open(info_file, O_RDWR|O_CREAT, 0600)) < 0) {
+       goto common_exit;
+    }
+
+    /*
+     * Create the internal info structure for this "tape".
+     */
+    amtable_alloc((void **)&volume_info,
+                 &open_count,
+                 sizeof(*volume_info),
+                 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].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;
+
+    /*
+     * Save the base directory name and see if we are "online".
+     */
+    volume_info[fd].basename = stralloc2(filename, "/data/");
+    if (check_online(fd)) {
+       save_errno = errno;
+       aclose(fd);
+       fd = -1;
+       amfree(volume_info[fd].basename);
+       errno = save_errno;
+       goto common_exit;
+    }
+
+common_exit:
+
+    amfree(info_file);
+
+    /*
+     * Return the info file descriptor as the unique descriptor for
+     * this open.
+     */
+    return fd;
+}
+
+ssize_t
+file_tapefd_read(fd, buffer, count)
+    int fd;
+    void *buffer;
+    size_t count;
+{
+    int result;
+    int file_fd;
+    int pos;
+    int record_size;
+    int read_size;
+
+    /*
+     * Make sure we are online.
+     */
+    if ((result = check_online(fd)) != 0) {
+       return result;
+    }
+    if (! volume_info[fd].is_online) {
+       errno = EIO;
+       return -1;
+    }
+
+    /*
+     * Do not allow any more reads after we find EOF.
+     */
+    if (volume_info[fd].at_eof) {
+       errno = EIO;
+       return -1;
+    }
+
+    /*
+     * If we are at EOM, set EOF and return a zero length result.
+     */
+    if (volume_info[fd].at_eom) {
+       volume_info[fd].at_eof = 1;
+       return 0;
+    }
+
+    /*
+     * Open the file, if needed.
+     */
+    if ((file_fd = file_open(fd)) < 0) {
+       return file_fd;
+    }
+
+    /*
+     * Make sure we do not read too much.
+     */
+    pos = volume_info[fd].file_current;
+    record_size = get_record_size(&volume_info[fd].fi[pos],
+                                 volume_info[fd].record_current);
+    if (record_size <= count) {
+       read_size = record_size;
+    } else {
+       read_size = count;
+    }
+
+    /*
+     * Read the data.  If we ask for less than the record size, skip to
+     * the next record boundary.
+     */
+    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);
+       }
+       volume_info[fd].record_current++;
+    } else if (result == 0) {
+       volume_info[fd].at_eof = 1;
+    }
+    return result;
+}
+
+ssize_t
+file_tapefd_write(fd, buffer, count)
+    int fd;
+    const void *buffer;
+    size_t count;
+{
+    int file_fd;
+    int write_count = count;
+    long length;
+    long kbytes_left;
+    int result;
+    int pos;
+
+    /*
+     * Make sure we are online.
+     */
+    if ((result = check_online(fd)) != 0) {
+       return result;
+    }
+    if (! volume_info[fd].is_online) {
+       errno = EIO;
+       return -1;
+    }
+
+    /*
+     * Check for write access first.
+     */
+    if ((volume_info[fd].flags & 3) == O_RDONLY) {
+       errno = EBADF;
+       return -1;
+    }
+
+    /*
+     * Special case: allow negative buffer size.
+     */
+    if (write_count <= 0) {
+       return 0;                               /* special case */
+    }
+
+    /*
+     * If we are at EOM, it takes precedence over EOF.
+     */
+    if (volume_info[fd].at_eom) {
+       volume_info[fd].at_eof = 0;
+    }
+
+#if 0 /*JJ*/
+    /*
+     * Writes are only allowed at BOF and EOM.
+     */
+    if (! (volume_info[fd].at_bof || volume_info[fd].at_eom)) {
+       errno = EIO;
+       return -1;
+    }
+#endif /*JJ*/
+
+    /*
+     * Writes are only allowed if we are not at EOF.
+     */
+    if (volume_info[fd].at_eof) {
+       errno = EIO;
+       return -1;
+    }
+
+    /*
+     * Open the file, if needed.
+     */
+    if((file_fd = volume_info[fd].fd) < 0) {
+       file_release(fd);
+       if ((file_fd = file_open(fd)) < 0) {
+           return file_fd;
+       }
+    }
+
+    /*
+     * Truncate the write if requested and return a simulated ENOSPC.
+     */
+    if ((length = tapefd_getinfo_length(fd)) > 0) {
+       kbytes_left = length - volume_info[fd].amount_written;
+       if (write_count / 1024 > kbytes_left) {
+           write_count = kbytes_left * 1024;
+       }
+    }
+    volume_info[fd].amount_written += (write_count + 1023) / 1024;
+    if (write_count <= 0) {
+       volume_info[fd].at_bof = 0;
+       volume_info[fd].at_eom = 1;
+       errno = ENOSPC;
+       return -1;
+    }
+
+    /*
+     * Do the write and truncate the file, if needed.  Checking for
+     * last_operation_write is an optimization so we only truncate
+     * once.
+     */
+    if (! volume_info[fd].last_operation_write) {
+       (void)ftruncate(file_fd, lseek(file_fd, 0, SEEK_CUR));
+       volume_info[fd].at_bof = 0;
+       volume_info[fd].at_eom = 1;
+    }
+    result = write(file_fd, buffer, 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++;
+    }
+
+    return result;
+}
+
+int
+file_tapefd_close(fd)
+    int fd;
+{
+    int pos;
+    int save_errno;
+    char *line;
+    int len;
+    char number[NUM_STR_SIZE];
+    int result;
+
+    /*
+     * 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 we are not at BOF, fsf to the next file unless we
+     * 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;
+       }
+    }
+
+    /*
+     * Close the file if it is still open.
+     */
+    file_close(fd);
+
+    /*
+     * Release the info structure areas.
+     */
+    for (pos = 0; pos < volume_info[fd].fi_limit; pos++) {
+       amfree(volume_info[fd].fi[pos].name);
+       amtable_free((void **)&volume_info[fd].fi[pos].ri,
+                    &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);
+    volume_info[fd].file_count = 0;
+    amfree(volume_info[fd].basename);
+
+    /*
+     * Update the status file if we were online.
+     */
+    if (volume_info[fd].is_online) {
+       if (lseek(fd, 0, SEEK_SET) != 0) {
+           save_errno = errno;
+           aclose(fd);
+           errno = save_errno;
+           return -1;
+       }
+       if (ftruncate(fd, 0) != 0) {
+           save_errno = errno;
+           aclose(fd);
+           errno = save_errno;
+           return -1;
+       }
+       ap_snprintf(number, sizeof(number),
+                   "%d", 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 >= 0) {
+               errno = ENOSPC;
+           }
+           save_errno = errno;
+           aclose(fd);
+           errno = save_errno;
+           return -1;
+       }
+    }
+
+    areads_relbuf(fd);
+    return close(fd);
+}
+
+void
+file_tapefd_resetofs(fd)
+    int fd;
+{
+}
+
+int
+file_tapefd_status(fd, stat)
+    int fd;
+    struct am_mt_status *stat;
+{
+    int result;
+
+    /*
+     * See if we are online.
+     */
+    if ((result = check_online(fd)) != 0) {
+       return result;
+    }
+    memset((void *)stat, 0, sizeof(*stat));
+    stat->online_valid = 1;
+    stat->online = volume_info[fd].is_online;
+    return 0;
+}
+
+int
+file_tape_stat(filename, buf)
+     char *filename;
+     struct stat *buf;
+{
+     return stat(filename, buf);
+}
+
+int
+file_tape_access(filename, mode)
+     char *filename;
+     int mode;
+{
+     return access(filename, mode);
+}
+
+int
+file_tapefd_rewind(fd)
+    int fd;
+{
+    int result = 0;
+
+    /*
+     * Make sure we are online.
+     */
+    if ((result = check_online(fd)) != 0) {
+       return result;
+    }
+    if (! volume_info[fd].is_online) {
+       errno = EIO;
+       return -1;
+    }
+
+    /*
+     * 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;
+       }
+    }
+
+    /*
+     * Close the file if it is still open.
+     */
+    file_close(fd);
+
+    /*
+     * Adjust the position and reset the flags.
+     */
+    volume_info[fd].file_current = 0;
+    volume_info[fd].record_current = 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;
+
+    return result;
+}
+
+int
+file_tapefd_unload(fd)
+    int fd;
+{
+    int result;
+
+    /*
+     * Make sure we are online.
+     */
+    if ((result = check_online(fd)) != 0) {
+       return result;
+    }
+    if (! volume_info[fd].is_online) {
+       errno = EIO;
+       return -1;
+    }
+
+    file_tapefd_rewind(fd);
+    return 0;
+}
+
+int
+file_tapefd_fsf(fd, count)
+    int fd, count;
+{
+    int result = 0;
+
+    /*
+     * Make sure we are online.
+     */
+    if ((result = check_online(fd)) != 0) {
+       return result;
+    }
+    if (! volume_info[fd].is_online) {
+       errno = EIO;
+       return -1;
+    }
+
+    /*
+     * If our last operation was a write and we are going to move
+     * backward, write a tapemark.
+     */
+    if (volume_info[fd].last_operation_write && count < 0) {
+       if ((result = file_tapefd_weof(fd, 1)) != 0) {
+           errno = EIO;
+           return -1;
+       }
+    }
+
+    /*
+     * Close the file if it is still open.
+     */
+    file_close(fd);
+
+    /*
+     * If we are at EOM and moving backward, adjust the count to go
+     * one more file.
+     */
+    if (volume_info[fd].at_eom && count < 0) {
+       count--;
+    }
+
+    /*
+     * Adjust the position and return an error if we go beyond either
+     * end of the tape.
+     */
+    volume_info[fd].file_current += count;
+    if (volume_info[fd].file_current > volume_info[fd].file_count) {
+        volume_info[fd].file_current = volume_info[fd].file_count;
+       errno = EIO;
+       result = -1;
+    } else if (volume_info[fd].file_current < 0) {
+        volume_info[fd].file_current = 0;
+       errno = EIO;
+       result = -1;
+    }
+    volume_info[fd].record_current = 0;
+
+    /*
+     * Set BOF to true so we can write.  Set to EOF to false if the
+     * fsf succeeded or if it failed but we were moving backward (and
+     * thus we are at beginning of tape), otherwise set it to true so
+     * a subsequent read will fail.  Set EOM to whatever is right.
+     * Reset amount_written if we ended up back at BOM.
+     */
+    volume_info[fd].at_bof = 1;
+    if (result == 0 || count < 0) {
+       volume_info[fd].at_eof = 0;
+    } else {
+       volume_info[fd].at_eof = 1;
+    }
+    volume_info[fd].at_eom
+      = (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;
+    }
+
+    return result;
+}
+
+int
+file_tapefd_weof(fd, count)
+    int fd, count;
+{
+    int file_fd;
+    int result = 0;
+    char *save_host;
+    char *save_disk;
+    int save_level;
+    int save_errno;
+
+    /*
+     * Make sure we are online.
+     */
+    if ((result = check_online(fd)) != 0) {
+       return result;
+    }
+    if (! volume_info[fd].is_online) {
+       errno = EIO;
+       return -1;
+    }
+
+    /*
+     * Check for write access first.
+     */
+    if ((volume_info[fd].flags & 3) == O_RDONLY) {
+       errno = EACCES;
+       return -1;
+    }
+
+    /*
+     * Special case: allow a zero count.
+     */
+    if (count == 0) {
+       return 0;                               /* special case */
+    }
+
+    /*
+     * Disallow negative count.
+     */
+    if (count < 0) {
+       errno = EINVAL;
+       return -1;
+    }
+
+    /*
+     * 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));
+       file_close(fd);
+       volume_info[fd].file_current++;
+       volume_info[fd].record_current = 0;
+       volume_info[fd].at_bof = 1;
+       volume_info[fd].at_eof = 0;
+       volume_info[fd].at_eom = 1;
+       volume_info[fd].last_operation_write = 0;
+       count--;
+    }
+
+    /*
+     * Release any data files from current through the end.
+     */
+    file_release(fd);
+
+    /*
+     * Save any labelling information in case we clobber it.
+     */
+    if ((save_host = tapefd_getinfo_host(fd)) != NULL) {
+       save_host = stralloc(save_host);
+    }
+    if ((save_disk = tapefd_getinfo_disk(fd)) != NULL) {
+       save_disk = stralloc(save_disk);
+    }
+    save_level = tapefd_getinfo_level(fd);
+
+    /*
+     * Add more tapemarks.
+     */
+    while (--count >= 0) {
+       if (file_open(fd) < 0) {
+           break;
+       }
+       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].at_bof = 1;
+       volume_info[fd].at_eof = 0;
+       volume_info[fd].at_eom = 1;
+       volume_info[fd].last_operation_write = 0;
+
+       /*
+        * Only the first "file" terminated by an EOF gets the naming
+        * information from the caller.
+        */
+       tapefd_setinfo_host(fd, NULL);
+       tapefd_setinfo_disk(fd, NULL);
+       tapefd_setinfo_level(fd, -1);
+    }
+
+    /*
+     * Restore the labelling information.
+     */
+    save_errno = errno;
+    tapefd_setinfo_host(fd, save_host);
+    amfree(save_host);
+    tapefd_setinfo_disk(fd, save_disk);
+    amfree(save_disk);
+    tapefd_setinfo_level(fd, save_level);
+    errno = save_errno;
+
+    return result;
+}
+
+int
+file_tapefd_can_fork(fd)
+    int fd;
+{
+    return 0;
+}
diff --git a/tape-src/output-file.h b/tape-src/output-file.h
new file mode 100644 (file)
index 0000000..727da96
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+
+/*
+ * $Id: output-file.h,v 1.1.2.2.2.2 2003/03/06 21:44:20 martinea Exp $
+ *
+ * tapeio.c virtual tape interface for a file device.
+ */
+
+#ifndef OUTPUT_FILE_H
+#define OUTPUT_FILE_H
+
+#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));
+
+#endif /* OUTPUT_FILE_H */
diff --git a/tape-src/output-null.c b/tape-src/output-null.c
new file mode 100644 (file)
index 0000000..fb8a46e
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+
+/*
+ * $Id: output-null.c,v 1.1.2.3.2.3 2003/03/06 21:44:20 martinea Exp $
+ *
+ * tapeio.c virtual tape interface for a null device.
+ */
+
+#include "amanda.h"
+
+#include "tapeio.h"
+#include "output-null.h"
+#include "fileheader.h"
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#endif
+
+static long *amount_written = NULL;
+static int open_count = 0;
+
+int
+null_tape_open(filename, flags, mask)
+    char *filename;
+    int flags;
+    int mask;
+{
+    int fd;
+
+    if ((flags & 3) != O_RDONLY) {
+       flags &= ~3;
+       flags |= O_RDWR;
+    }
+    if ((fd = open("/dev/null", flags, mask)) >= 0) {
+       tapefd_setinfo_fake_label(fd, 1);
+       amtable_alloc((void **)&amount_written,
+                     &open_count,
+                     sizeof(*amount_written),
+                     fd + 1,
+                     10,
+                     NULL);
+       amount_written[fd] = 0;
+    }
+    return fd;
+}
+
+ssize_t
+null_tapefd_read(fd, buffer, count)
+    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;
+{
+    int write_count = count;
+    long length;
+    long kbytes_left;
+    int r;
+
+    if (write_count <= 0) {
+       return 0;                               /* special case */
+    }
+
+    if ((length = tapefd_getinfo_length(fd)) > 0) {
+       kbytes_left = length - amount_written[fd];
+       if (write_count / 1024 > kbytes_left) {
+           write_count = kbytes_left * 1024;
+       }
+    }
+    amount_written[fd] += (write_count + 1023) / 1024;
+    if (write_count <= 0) {
+       errno = ENOSPC;
+       r = -1;
+    } else {
+       r = write(fd, buffer, write_count);
+    }
+    return r;
+}
+
+int
+null_tapefd_close(fd)
+    int fd;
+{
+    return close(fd);
+}
+
+void
+null_tapefd_resetofs(fd)
+    int fd;
+{
+}
+
+int
+null_tapefd_status(fd, stat)
+    int fd;
+    struct am_mt_status *stat;
+{
+    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;
+{
+     return stat("/dev/null", buf);
+}
+
+int
+null_tape_access(filename, mode)
+     char *filename;
+     int mode;
+{
+     return access("/dev/null", mode);
+}
+
+int
+null_tapefd_rewind(fd)
+    int fd;
+{
+    amount_written[fd] = 0;
+    return 0;
+}
+
+int
+null_tapefd_unload(fd)
+    int fd;
+{
+    amount_written[fd] = 0;
+    return 0;
+}
+
+int
+null_tapefd_fsf(fd, count)
+    int fd, count;
+{
+    return 0;
+}
+
+int
+null_tapefd_weof(fd, count)
+    int fd, count;
+{
+    return 0;
+}
+
+int 
+null_tapefd_can_fork(fd)
+    int fd;
+{
+    return 0;
+}
+
diff --git a/tape-src/output-null.h b/tape-src/output-null.h
new file mode 100644 (file)
index 0000000..72c37a5
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+
+/*
+ * $Id: output-null.h,v 1.1.2.2.2.2 2003/03/06 21:44:20 martinea Exp $
+ *
+ * tapeio.c virtual tape interface for a null device.
+ */
+
+#ifndef OUTPUT_NULL_H
+#define OUTPUT_NULL_H
+
+#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));
+
+#endif /* OUTPUT_NULL_H */
diff --git a/tape-src/output-rait.c b/tape-src/output-rait.c
new file mode 100644 (file)
index 0000000..3c40f1f
--- /dev/null
@@ -0,0 +1,1221 @@
+#ifdef NO_AMANDA
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#else
+#include "amanda.h"
+#include "tapeio.h"
+#endif
+
+#include "output-rait.h"
+#include "output-tape.h"
+
+#ifdef NO_AMANDA
+#define        amfree(x)       do {                                            \
+       int save_errno = errno;                                         \
+       free(x);                                                        \
+       (x) = 0;                                                        \
+       errno = save_errno;                                             \
+} while(0)
+#define        tape_open       open
+#define tapefd_read    read
+#define tapefd_write   write
+#define tapefd_close   close
+#define tape_access    access
+#define tape_stat      stat
+#define tapefd_fsf     tape_tapefd_fsf
+#define tapefd_rewind  tape_tapefd_rewind
+#define tapefd_status  tape_tapefd_status
+#define tapefd_unload  tape_tapefd_unload
+#define tapefd_weof    tape_tapefd_weof
+
+int tapeio_init_devname (char * dev,
+                        char **dev_left,
+                        char **dev_right,
+                        char **dev_next);
+char *tapeio_next_devname (char * dev_left,
+                          char * dev_right,
+                          char **dev_next);
+#endif
+
+/*
+** RAIT -- redundant array of (inexpensive?) tapes
+**
+** Author: Marc Mengel <mengel@fnal.gov>
+**
+** This package provides for striping input/output across
+** multiple tape drives.
+**
+                Table of Contents
+
+  rait.c..................................................1
+       MAX_RAITS.........................................2
+        rait_table........................................2
+       rait_open(char *dev, int flags, int 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_ioctl(int fd, int op, void *p)...............8
+       rait_access(devname, R_OK|W_OK)...................8
+       rait_stat(devname, struct statbuf*)...............8
+       rait_copy(char *f1, char *f2).....................9
+       ifndef NO_AMANDA
+           rait_tapefd_fsf(rait_tapefd, count)..........10
+           rait_tapefd_rewind(rait_tapefd)..............10
+           rait_tapefd_resetofs(rait_tapefd)............10
+           rait_tapefd_unload(rait_tapefd)..............10
+           rait_tapefd_status(rait_tapefd, stat)........10
+           rait_tapefd_weof(rait_tapefd, count).........10
+
+       
+
+   rait.h.................................................1
+        typedef RAIT......................................1
+        ifdef RAIT_REDIRECT...............................1
+             open.........................................1
+            close........................................1
+             ioctl........................................1
+            read.........................................1
+             write........................................1
+*/
+
+/*\f*/
+
+/*
+** rait_open takes a string like:
+** "/dev/rmt/tps0d{3,5,7,19}nrnsv"
+** and opens
+** "/dev/rmt/tps0d3nrnsv"
+** "/dev/rmt/tps0d5nrnsv"
+** "/dev/rmt/tps0d7nrnsv"
+** "/dev/rmt/tps0d19nrnsv"
+** as a RAIT.
+**
+** If it has no curly brace, we treat it as a plain device,
+** and do a normal open, and do normal operations on it.
+*/
+
+#ifdef RAIT_DEBUG
+#define rait_debug(p) do {                                             \
+  int save_errno = errno;                                              \
+                                                                       \
+  if (0!=getenv("RAIT_DEBUG")) {                                       \
+    fprintf p;                                                         \
+  }                                                                    \
+  errno = save_errno;                                                  \
+} while (0)
+#else
+#define rait_debug(p)
+#endif
+
+static RAIT *rait_table = 0;           /* table to keep track of RAITS */
+static int rait_table_count;
+
+#ifdef NO_AMANDA
+/*
+ * amtable_alloc -- (re)allocate enough space for some number of elements.
+ *
+ * input:      table -- pointer to pointer to table
+ *             current -- pointer to current number of elements
+ *             elsize -- size of a table element
+ *             count -- desired number of elements
+ *             bump -- round up factor
+ * output:     table -- possibly adjusted to point to new table area
+ *             current -- possibly adjusted to new number of elements
+ */
+
+static int
+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;
+       }
+       if (0 != *table) {
+           memcpy(table_new, *table, *current * elsize);
+           amfree(*table);
+       }
+       *table = table_new;
+       memset(((char *)*table) + *current * elsize,
+              0,
+              (table_count_new - *current) * elsize);
+       *current = table_count_new;
+    }
+    return 0;
+}
+
+/*
+ * amtable_free -- release a table.
+ *
+ * input:      table -- pointer to pointer to table
+ *             current -- pointer to current number of elements
+ * output:     table -- possibly adjusted to point to new table area
+ *             current -- possibly adjusted to new number of elements
+ */
+
+void
+amtable_free(table, current)
+    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,                       \
+                                             NULL)
+
+int
+rait_open(char *dev, int flags, int mask) {
+    int fd;                    /* the file descriptor number to return */
+    RAIT *res;                 /* resulting RAIT structure */
+    char *dev_left;            /* string before { */
+    char *dev_right;           /* string after } */
+    char *dev_next;            /* string inside {} */
+    char *dev_real;            /* parsed device name */
+    int rait_flag;             /* true if RAIT syntax in dev */
+    int save_errno;
+    int r;
+
+    rait_debug((stderr,"rait_open( %s, %d, %d )\n", dev, flags, mask));
+
+    rait_flag = (0 != strchr(dev, '{'));
+
+    if (rait_flag) {
+
+       /*
+       ** we have to return a valid file descriptor, so use
+       ** a dummy one to /dev/null
+       */
+       fd = open("/dev/null",flags,mask);
+    } else {
+
+       /*
+       ** call the normal tape_open function if we are not
+       ** going to do RAIT
+       */
+       fd = tape_open(dev,flags,mask);
+    }
+    if(-1 == fd) {
+       rait_debug((stderr, "rait_open:returning %d: %s\n",
+                           fd,
+                           strerror(errno)));
+       return fd;
+    }
+
+    if(0 != rait_table_alloc(fd + 1)) {
+       save_errno = errno;
+       (void)tapefd_close(fd);
+       errno = save_errno;
+       rait_debug((stderr, "rait_open:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    res = &rait_table[fd];
+
+    memset(res, 0, sizeof(*res));
+    res->nopen = 1;
+
+    res->fd_count = 0;
+    if (rait_flag) {
+
+       /* copy and parse the dev string so we can scribble on it */
+       dev = stralloc(dev);
+       if (0 == dev) {
+           rait_debug((stderr, "rait_open:returning %d: %s\n",
+                               -1,
+                               "out of stralloc memory"));
+           return -1;
+        }
+        if (0 != tapeio_init_devname(dev, &dev_left, &dev_right, &dev_next)) {
+           rait_debug((stderr, "rait_open:returning %d: %s\n",
+                               -1,
+                               strerror(errno)));
+           return -1;
+        }
+
+       while (0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {
+           r = amtable_alloc((void **)&res->fds,
+                           &res->fd_count,
+                           sizeof(*res->fds),
+                           res->nfds + 1,
+                           10,
+                           NULL);
+           if (0 != r) {
+               (void)rait_close(fd);
+               fd = -1;
+               amfree(dev_real);
+               break;
+           }
+           res->fds[ res->nfds ] = tape_open(dev_real,flags,mask);
+           rait_debug((stderr,"rait_open:opening %s yields %d\n",
+                       dev_real, res->fds[res->nfds] ));
+           if ( res->fds[res->nfds] < 0 ) {
+               save_errno = errno;
+               (void)rait_close(fd);
+               amfree(dev_real);
+               errno = save_errno;
+               fd = -1;
+               break;
+           }
+           tapefd_set_master_fd(res->fds[res->nfds], fd);
+           amfree(dev_real);
+           res->nfds++;
+       }
+
+       /* clean up our copied string */
+       amfree(dev);
+
+    } else {
+
+       /*
+       ** set things up to treat this as a normal tape if we ever
+       ** come in here again
+       */
+
+       res->nfds = 0;
+       r = amtable_alloc((void **)&res->fds,
+                         &res->fd_count,
+                         sizeof(*res->fds),
+                         res->nfds + 1,
+                         1,
+                         NULL);
+       if (0 != r) {
+           (void)tapefd_close(fd);
+           memset(res, 0, sizeof(*res));
+           errno = ENOMEM;
+           fd = -1;
+       } else {
+           res->fds[res->nfds] = fd;
+           res->nfds++;
+       }
+    }
+
+    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));
+       }
+    }
+
+    rait_debug((stderr, "rait_open:returning %d%s%s\n",
+                       fd,
+                       (fd < 0) ? ": " : "",
+                       (fd < 0) ? strerror(errno) : ""));
+
+    return fd;
+}
+
+#ifdef NO_AMANDA
+int
+tapeio_init_devname(char * dev,
+                   char **dev_left,
+                   char **dev_right,
+                   char **dev_next) {
+    /*
+    ** find the first { and then the first } that follows it
+    */
+    if ( 0 == (*dev_next = strchr(dev, '{'))
+        || 0 == (*dev_right = strchr(*dev_next + 1, '}')) ) {
+       /* we dont have a {} pair */
+       amfree(dev);
+       errno = EINVAL;
+       return -1;
+    }
+
+    *dev_left = dev;                           /* before the { */
+    **dev_next = 0;                            /* zap the { */
+    (*dev_next)++;
+    (*dev_right)++;                            /* after the } */
+    return 0;
+}
+
+char *
+tapeio_next_devname(char * dev_left,
+                   char * dev_right,
+                   char **dev_next) {
+    char *dev_real = 0;
+    char *next;
+    int len;
+
+    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 */
+       }
+    }
+    return dev_real;
+}
+#endif
+
+/*
+** close everything we opened and free our memory.
+*/
+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;
+
+    rait_debug((stderr,"rait_close( %d )\n", fd));
+
+    if (fd < 0 || fd >= rait_table_count) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_close:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    pr = &rait_table[fd];
+    if (0 == pr->nopen) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_close:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    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));
+    }
+
+    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
+    ** activities like filemark writes, etc.)
+    */
+    for( i = 0; i < pr->nfds; i++ ) {
+       if(tapefd_can_fork(pr->fds[i])) {
+           if ((kid = fork()) == 0) {
+               /* we are the child process */
+               sleep(0);
+               j = tapefd_close(pr->fds[i]);
+               exit(j);
+            } else {
+               /* remember who the child is or that an error happened */
+               pr->readres[i] = kid;
+            }
+       }
+       else {
+           j = tapefd_close(pr->fds[i]);
+           if ( j != 0 )
+               res = j;
+           pr->readres[i] = -1;
+       }
+    }
+
+    for( i = 0; i < pr->nfds; i++ ) {
+       j = tapefd_close(pr->fds[i]);
+       if ( j != 0 )
+           res = j;
+    }
+
+    for( i = 0; i < pr->nfds; i++ ) {
+        int stat;
+       if(pr->readres[i] != -1) {
+           waitpid( pr->readres[i], &stat, 0);
+           if( WEXITSTATUS(stat) != 0 ) {
+               res = WEXITSTATUS(stat);
+               if( res == 255 ) 
+                   res = -1;
+           }
+        }
+    }
+    if (pr->nfds > 1) {
+       (void)close(fd);        /* close the dummy /dev/null descriptor */
+    }
+    if (0 != pr->fds) {
+       amtable_free((void **)&pr->fds, &pr->fd_count);
+    }
+    if (0 != pr->readres) {
+       amfree(pr->readres);
+    }
+    if (0 != pr->xorbuf) {
+       amfree(pr->xorbuf);
+    }
+    pr->nopen = 0;
+    errno = save_errno;
+    rait_debug((stderr, "rait_close:returning %d%s%s\n",
+                       res,
+                       (res < 0) ? ": " : "",
+                       (res < 0) ? strerror(errno) : ""));
+    return res;
+}
+
+/*\f*/
+
+/*
+** 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) {
+    int i;                     /* drive number in RAIT */
+    long 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));
+
+    if (fd < 0 || fd >= rait_table_count) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_lseek:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    pr = &rait_table[fd];
+    if (0 == pr->nopen) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_lseek:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    if (pr->nfds > 1 && (pos % (pr->nfds-1)) != 0) {
+       errno = EDOM;
+       total = -1;
+    } else {
+       total = 0;
+       pos = pos / pr->nfds;
+       for( i = 0; i < pr->nfds; i++ ) {
+           if (0 >= (res = lseek(pr->fds[i], pos, whence))) {
+               total = res;
+               break;
+           }
+           total += res;
+       }
+    }
+    rait_debug((stderr, "rait_lseek:returning %ld%s%s\n",
+                       total,
+                       (total < 0) ? ": " : "",
+                       (total < 0) ? strerror(errno) : ""));
+    return total;
+}
+
+/*\f*/
+
+/*
+** 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) {
+    const char *buf = bufptr;
+    int i = 0, j;      /* drive number, byte offset */
+    RAIT *pr;          /* RAIT structure for this RAIT */
+    int res, 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) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_write:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    pr = &rait_table[fd];
+    if (0 == pr->nopen) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_write:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    /* need to be able to slice it up evenly... */
+    if (pr->nfds > 1) {
+       data_fds = pr->nfds - 1;
+       if (0 != len % data_fds) {
+           errno = EDOM;
+           rait_debug((stderr, "rait_write:returning %d: %s\n",
+                               -1,
+                               strerror(errno)));
+           return -1;
+       }
+       /* each slice gets an even portion */
+       len = len / data_fds;
+
+       /* make sure we have enough buffer space */
+       if (len > 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->xorbuflen = len;
+       }
+
+       /* compute the sum */
+       memcpy(pr->xorbuf, buf, len);
+       for( i = 1; i < data_fds; i++ ) {
+           for( j = 0; j < len; j++ ) {
+               pr->xorbuf[j] ^= buf[len * i + j];
+           }
+       }
+    } else {
+       data_fds = pr->nfds;
+    }
+
+    /* 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",
+                       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 (total >= 0 && pr->nfds > 1) {
+        /* write the sum, don't include it in the total bytes written */
+       res = tapefd_write(pr->fds[i], pr->xorbuf, len);
+       rait_debug((stderr, "rait_write: write(%d,%lx,%d) returns %d%s%s\n",
+                   pr->fds[i],
+                   (unsigned long)pr->xorbuf,
+                   len,
+                   res,
+                   (res < 0) ? ": " : "",
+                   (res < 0) ? strerror(errno) : ""));
+       if (res < 0) {
+           total = res;
+       }
+    }
+
+    rait_debug((stderr, "rait_write:returning %d%s%s\n",
+                       total,
+                       (total < 0) ? ": " : "",
+                       (total < 0) ? strerror(errno) : ""));
+
+    return total;
+}
+
+/*\f*/
+
+/*
+** once again, if there is one data stream do a read, otherwise
+** do all n reads, and if any of the first n - 1 fail, compute
+** 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 
+** garble the data...
+*/
+ssize_t 
+rait_read(int fd, void *bufptr, size_t len) {
+    char *buf = bufptr;
+    int nerrors, 
+        neofs, 
+        total, 
+        errorblock;
+    int i,j;
+    RAIT *pr;
+    int data_fds;
+    int save_errno = errno;
+    int 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) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_read:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    pr = &rait_table[fd];
+    if (0 == pr->nopen) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_read:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    nerrors = 0;
+    neofs = 0;
+    total = 0;
+    errorblock = -1;
+    /* once again , we slice it evenly... */
+    if (pr->nfds > 1) {
+       data_fds = pr->nfds - 1;
+       if (0 != len % data_fds) {
+           errno = EDOM;
+           rait_debug((stderr, "rait_read:returning %d: %s\n",
+                               -1,
+                               strerror(errno)));
+           return -1;
+       }
+       len = len / data_fds;
+    } else {
+       data_fds = 1;
+    }
+
+    /* try all the reads, save the result codes */
+    /* count the eof/errors */
+    for( i = 0; i < data_fds; i++ ) {
+       pr->readres[i] = tapefd_read(pr->fds[i], buf + len*i , len);
+       rait_debug((stderr, "rait_read: read on fd %d returns %d%s%s\n",
+                   pr->fds[i],
+                   pr->readres[i],
+                   (pr->readres[i] < 0) ? ": " : "",
+                   (pr->readres[i] < 0) ? strerror(errno) : ""));
+       if ( pr->readres[i] <= 0 ) {
+           if ( pr->readres[i] == 0 ) {
+               neofs++;
+           } else {
+               if (0 == nerrors) {
+                   save_errno = errno;
+               }
+               nerrors++;
+           }
+           errorblock = i;
+       } else if (pr->readres[i] > maxreadres) {
+           maxreadres = pr->readres[i];
+       }
+    }
+    if (pr->nfds > 1) {
+       /* make sure we have enough buffer space */
+       if (len > 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->xorbuflen = len;
+       }
+       pr->readres[i] = tapefd_read(pr->fds[i], pr->xorbuf , len);
+       rait_debug((stderr, "rait_read: read on fd %d returns %d%s%s\n",
+                   pr->fds[i],
+                   pr->readres[i],
+                   (pr->readres[i] < 0) ? ": " : "",
+                   (pr->readres[i] < 0) ? strerror(errno) : ""));
+    }
+
+    /*
+     * Make sure all the reads were the same length
+     */
+    for (j = 0; j < pr->nfds; j++) {
+       if (pr->readres[j] != maxreadres) {
+           nerrors++;
+           errorblock = j;
+       }
+    }
+
+    /*
+     * If no errors, check that the xor sum matches
+     */
+    if ( nerrors == 0 && pr->nfds > 1  ) {
+       for(i = 0; i < maxreadres; i++ ) {
+          int sum = 0;
+          for(j = 0; j < pr->nfds - 1; j++) {
+              sum ^= (buf + len * j)[i];
+           }
+          if (sum != pr->xorbuf[i]) {
+             sum_mismatch = 1;
+          }
+       }
+    }
+
+    /* 
+    ** 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
+    ** anything else fails
+    */
+
+    if (neofs == pr->nfds) {
+       rait_debug((stderr, "rait_read:returning 0\n"));
+       return 0;
+    }
+
+    if (sum_mismatch) {
+       errno = EDOM;
+       rait_debug((stderr, "rait_read:returning %d: %s\n",
+                           -1,
+                           "XOR block mismatch"));
+       return -1;
+    }
+
+    if (nerrors > 1 || (pr->nfds <= 1 && nerrors > 0)) {
+       errno = save_errno;
+       rait_debug((stderr, "rait_read:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    /*
+    ** so now if we failed on a data block, we need to do a recovery
+    ** if we failed on the xor block -- who cares?
+    */
+    if (nerrors == 1 && pr->nfds > 1 && errorblock != pr->nfds-1) {
+
+       rait_debug((stderr, "rait_read: fixing data from fd %d\n",
+                           pr->fds[errorblock]));
+
+       /* the reads were all *supposed* to be the same size, so... */
+       pr->readres[errorblock] = maxreadres;
+
+       /* fill it in first with the xor sum */
+       memcpy(buf + len * errorblock, pr->xorbuf, len);
+
+       /* xor back out the other blocks */
+       for( i = 0; i < data_fds; i++ ) {
+           if( i != errorblock ) {
+               for( j = 0; j < len ; j++ ) {
+                   buf[j + len * errorblock] ^= buf[j + len * i];
+               }
+           }
+       }
+       /* there, now the block is back as if it never failed... */
+    }
+
+    /* 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]);
+        }
+       total += pr->readres[i];
+    }
+
+    rait_debug((stderr, "rait_read:returning %d%s%s\n",
+                       total,
+                       (total < 0) ? ": " : "",
+                       (total < 0) ? strerror(errno) : ""));
+
+    return total;
+}
+
+/*\f*/
+
+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) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_ioctl:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    pr = &rait_table[fd];
+    if (0 == pr->nopen) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_ioctl:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    for( i = 0; i < pr->nfds ; i++ ) {
+       res = ioctl(pr->fds[i], op, p);
+       if ( res != 0 ) { 
+           errors++;
+           if (errors > 1) {
+               break;
+           }
+           res = 0;
+       }
+    }
+
+    rait_debug((stderr, "rait_ioctl: returning %d%s%s\n",
+                       res,
+                       (res < 0) ? ": " : "",
+                       (res < 0) ? strerror(errno) : ""));
+
+    return res;
+}
+
+/*
+** access() all the devices, returning if any fail
+*/
+int rait_access(char *devname, int flags) {
+    int res = 0;
+    char *dev_left;            /* string before { */
+    char *dev_right;           /* string after } */
+    char *dev_next;            /* string inside {} */
+    char *dev_real;            /* parsed device name */
+
+    /* copy and parse the dev string so we can scribble on it */
+    devname = stralloc(devname);
+    if (0 == devname) {
+       rait_debug((stderr, "rait_access:returning %d: %s\n",
+                           -1,
+                           "out of stralloc memory"));
+       return -1;
+    }
+    if ( 0 != tapeio_init_devname(devname, &dev_left, &dev_right, &dev_next)) {
+       rait_debug((stderr, "rait_access:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    while( 0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {
+       res = tape_access(dev_real, flags);
+       rait_debug((stderr,"rait_access:access( %s, %d ) yields %d\n",
+               dev_real, flags, res ));
+       amfree(dev_real);
+       if (res < 0) { 
+           break;
+        }
+    }
+    amfree(devname);
+
+    rait_debug((stderr, "rait_access: returning %d%s%s\n",
+                       res,
+                       (res < 0) ? ": " : "",
+                       (res < 0) ? strerror(errno) : ""));
+
+    return res;
+}
+
+/*
+** stat all the devices, returning the last one unless one fails
+*/
+int rait_stat(char *devname, struct stat *buf) {
+    int res = 0;
+    char *dev_left;            /* string before { */
+    char *dev_right;           /* string after } */
+    char *dev_next;            /* string inside {} */
+    char *dev_real;            /* parsed device name */
+
+    /* copy and parse the dev string so we can scribble on it */
+    devname = stralloc(devname);
+    if (0 == devname) {
+       rait_debug((stderr, "rait_access:returning %d: %s\n",
+                           -1,
+                           "out of stralloc memory"));
+       return -1;
+    }
+    if ( 0 != tapeio_init_devname(devname, &dev_left, &dev_right, &dev_next)) {
+       rait_debug((stderr, "rait_access:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    while( 0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {
+       res = tape_stat(dev_real, 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) { 
+           break;
+        }
+    }
+    amfree(devname);
+
+    rait_debug((stderr, "rait_access: returning %d%s%s\n",
+                       res,
+                       (res < 0) ? ": " : "",
+                       (res < 0) ? strerror(errno) : ""));
+
+    return res;
+}
+
+/*\f*/
+
+int rait_copy(char *f1, char *f2, int buflen) {
+    int t1, t2;
+    int len, wres;
+    char *buf;
+    int save_errno;
+
+    t1 = rait_open(f1,O_RDONLY,0644);
+    if (t1 < 0) {
+       return t1;
+    }
+    t2 = rait_open(f2,O_CREAT|O_RDWR,0644);
+    if (t2 < 0) {
+       save_errno = errno;
+       (void)rait_close(t1);
+       errno = save_errno;
+       return -1;
+    }
+    buf = malloc(buflen);
+    if (0 == buf) {
+       (void)rait_close(t1);
+       (void)rait_close(t2);
+       errno = ENOMEM;
+       return -1;
+    }
+    do {
+       len = rait_read(t1,buf,buflen);
+       if (len > 0 ) {
+           wres = rait_write(t2, buf, len);
+           if (wres < 0) {
+               len = -1;
+               break;
+           }
+       }
+    } while( len > 0 );
+    save_errno = errno;
+    amfree(buf);
+    (void)rait_close(t1);
+    (void)rait_close(t2);
+    errno = save_errno;
+    return (len < 0) ? -1 : 0;
+}
+
+/*\f*/
+
+/*
+** Amanda Tape API routines:
+*/
+
+static int rait_tapefd_ioctl(int (*func0)(int),
+                            int (*func1)(int, int),
+                            int fd,
+                            int count) {
+    int i, j, res = 0;
+    RAIT *pr;
+    int errors = 0;
+    int kid;
+    int stat;
+
+    rait_debug((stderr, "rait_tapefd_ioctl(%d,%d)\n",fd,count));
+
+    if (fd < 0 || fd >= rait_table_count) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_tapefd_ioctl:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    pr = &rait_table[fd];
+    if (0 == pr->nopen) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_tapefd_ioctl:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    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));
+    }
+
+    for( i = 0; i < pr->nfds ; i++ ) {
+       if(tapefd_can_fork(pr->fds[i])) {
+            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) {
+                   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));
+               if (kid == 0)
+                   exit(res);
+            } else {
+               rait_debug((stderr, "in parent, fork returned %d\n", kid));
+               pr->readres[i] = kid;
+            }
+       }
+       else {
+           if(0 != func0) {
+               j = (*func0)(pr->fds[i]);
+           } else {
+               j = (*func1)(pr->fds[i], count);
+           }
+           if( j != 0) {
+               errors++;
+           }
+           pr->readres[i] = -1;
+       }
+    }
+    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 ) 
+                   res = -1;
+            }
+            rait_debug((stderr, "in parent, return code was %d\n", res));
+           if ( res != 0 ) { 
+               errors++;
+               res = 0;
+           }
+       }
+    }
+    if (errors > 0) {
+       res = -1;
+    }
+
+    rait_debug((stderr, "rait_tapefd_ioctl: returning %d%s%s\n",
+                       res,
+                       (res < 0) ? ": " : "",
+                       (res < 0) ? strerror(errno) : ""));
+
+    return res;
+}
+
+int rait_tapefd_fsf(int fd, int count) {
+    return rait_tapefd_ioctl(0, tapefd_fsf, fd, count);
+}
+
+int rait_tapefd_rewind(int fd) {
+    return rait_tapefd_ioctl(tapefd_rewind, 0, fd, -1);
+}
+
+int rait_tapefd_unload(int fd) {
+    return rait_tapefd_ioctl(tapefd_unload, 0, fd, -1);
+}
+
+int rait_tapefd_weof(int fd, int count) {
+    return rait_tapefd_ioctl(0, tapefd_weof, fd, count);
+}
+
+int rait_tape_open(char *name, int flags, int mask) {
+    return rait_open(name, flags, mask);
+}
+
+int rait_tapefd_status(int fd, struct am_mt_status *stat) {
+    int i;
+    RAIT *pr;
+    int res = 0;
+    int errors = 0;
+
+    rait_debug((stderr, "rait_tapefd_status(%d)\n",fd));
+
+    if (fd < 0 || fd >= rait_table_count) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_tapefd_status:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    pr = &rait_table[fd];
+    if (0 == pr->nopen) {
+       errno = EBADF;
+       rait_debug((stderr, "rait_tapefd_status:returning %d: %s\n",
+                           -1,
+                           strerror(errno)));
+       return -1;
+    }
+
+    for( i = 0; i < pr->nfds ; i++ ) {
+       res = tapefd_status(pr->fds[i], stat);
+       if(res != 0) {
+           errors++;
+       }
+    }
+    if (errors > 0) {
+       res = -1;
+    }
+    return res;
+}
+
+void rait_tapefd_resetofs(int fd) {
+    rait_lseek(fd,  0L, SEEK_SET);
+}
+
+int 
+rait_tapefd_can_fork(fd)
+    int fd;
+{
+    return 0;
+}
+
diff --git a/tape-src/output-rait.h b/tape-src/output-rait.h
new file mode 100644 (file)
index 0000000..09d890c
--- /dev/null
@@ -0,0 +1,120 @@
+#ifndef RAIT_H
+
+#define RAIT_H
+
+typedef struct {
+    int nopen;
+    int nfds;
+    int fd_count;
+    int *fds;
+    int *readres;
+    int 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
+ * interested in from the free-for-all of what the various drivers
+ * supply.
+ */
+
+struct am_mt_status {
+    char online_valid;                 /* is the online flag valid? */
+    char bot_valid;                    /* is the BOT flag valid? */
+    char eot_valid;                    /* is the EOT flag valid? */
+    char protected_valid;              /* is the protected flag valid? */
+    char flags_valid;                  /* is the flags field valid? */
+    char fileno_valid;                 /* is the fileno field valid? */
+    char blkno_valid;                  /* is the blkno field valid? */
+    char device_status_valid;          /* is the device status field valid? */
+    char error_status_valid;           /* is the device status field valid? */
+
+    char online;                       /* true if device is online/ready */
+    char bot;                          /* true if tape is at the beginning */
+    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 */
+    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 */
+    unsigned long error_status;                /* "error status", whatever that is */
+};
+#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));
+
+#ifdef RAIT_REDIRECT
+
+/* handle ugly Solaris stat mess */
+
+#ifdef _FILE_OFFSET_BITS
+#include <sys/stat.h>
+#undef stat
+#undef open
+#if _FILE_OFFSET_BITS == 64
+struct stat {
+       dev_t   st_dev;
+       long    st_pad1[3];     /* reserved for network id */
+       ino_t   st_ino;
+       mode_t  st_mode;
+       nlink_t st_nlink;
+       uid_t   st_uid;
+       gid_t   st_gid;
+       dev_t   st_rdev;
+       long    st_pad2[2];
+       off_t   st_size;
+       timestruc_t st_atim;
+       timestruc_t st_mtim;
+       timestruc_t st_ctim;
+       long    st_blksize;
+       blkcnt_t st_blocks;
+       char    st_fstype[_ST_FSTYPSZ];
+       long    st_pad4[8];     /* expansion area */
+};
+#endif
+
+#endif
+
+#define access(p,f)    rait_access(p,f)
+#define stat(a,b)      rait_stat(a,b)
+#define open           rait_open
+#define        close(a)        rait_close(a)
+#define read(f,b,l)    rait_read(f,b,l)
+#define write(f,b,l)   rait_write(f,b,l)
+#define        ioctl(f,n,x)    rait_ioctl(f,n,x)
+#endif
+
+#endif
diff --git a/tape-src/output-tape.c b/tape-src/output-tape.c
new file mode 100644 (file)
index 0000000..bd36965
--- /dev/null
@@ -0,0 +1,650 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+
+/*
+ * $Id: output-tape.c,v 1.1.2.6.2.7 2003/03/06 21:44:21 martinea Exp $
+ *
+ * tapeio.c virtual tape interface for normal tape drives.
+ */
+
+#ifdef NO_AMANDA
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#else
+#include "amanda.h"
+#include "tapeio.h"
+#endif
+
+#include "output-tape.h"
+
+#ifndef NO_AMANDA
+#include "fileheader.h"
+#endif
+
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#endif
+
+/*
+=======================================================================
+** Here are the ioctl() interface routines, which are #ifdef-ed
+** heavily by platform.
+=======================================================================
+*/
+
+#if defined(HAVE_BROKEN_FSF)                                           /* { */
+/*
+ * tape_tapefd_fsf -- handle systems that have a broken fsf operation
+ * and cannot do an fsf operation unless they are positioned at a tape
+ * mark (or BOT).  Sheesh!  This shows up in amrestore as I/O errors
+ * when skipping.
+ */
+
+int
+tape_tapefd_fsf(fd, count)
+    int fd;
+    int count;
+{
+    size_t buflen;
+    char *buffer = NULL;
+    int len = 0;
+
+    buflen = MAX_TAPE_BLOCK_BYTES;
+    buffer = alloc(buflen);
+
+    while(--count >= 0) {
+       while((len = tapefd_read(fd, buffer, buflen)) > 0) {}
+       if(len < 0) {
+           break;
+       }
+    }
+    amfree(buffer);
+    return len;
+}
+#endif                                                                 /* } */
+
+#ifdef UWARE_TAPEIO                                                    /* { */
+
+#include <sys/tape.h>
+
+/*
+ * Rewind a tape to the beginning.
+ */
+int
+tape_tapefd_rewind(fd)
+    int fd;
+{
+    int st;
+
+    return ioctl(fd, T_RWD, &st);
+}
+
+/*
+ * Rewind and unload a tape.
+ */
+int
+tape_tapefd_unload(fd)
+    int fd;
+{
+    int st;
+
+    return ioctl(fd, T_OFFL, &st);
+}
+
+#if !defined(HAVE_BROKEN_FSF)
+/*
+ * Forward space the tape device count files.
+ */
+int tape_tapefd_fsf(fd, count)
+    int fd, count;
+{
+    int st;
+    int status;
+
+    while (--count >= 0) {
+        if ((status = ioctl(fd, T_SFF, &st)) != 0) {
+            break;
+       }
+    }
+
+    return status;
+}
+#endif
+
+/*
+ * Write some number of end of file marks (a.k.a. tape marks).
+ */
+int
+tape_tapefd_weof(fd, count)
+    int fd, count;
+{
+    int st;
+    int status;
+
+    while (--count >= 0) {
+        if ((status = ioctl(fd, T_WRFILEM, &st)) != 0) {
+            break;
+       }
+    }
+
+    return status;
+}
+
+#else                                                                  /* }{ */
+#ifdef AIX_TAPEIO                                                      /* { */
+
+#include <sys/tape.h>
+
+/*
+ * Rewind a tape to the beginning.
+ */
+int
+tape_tapefd_rewind(fd)
+    int fd;
+{
+    struct stop st;
+
+    st.st_op = STREW;
+    st.st_count = 1;
+
+    return ioctl(fd, STIOCTOP, &st);
+}
+
+/*
+ * Rewind and unload a tape.
+ */
+int
+tape_tapefd_unload(fd)
+    int fd;
+{
+    struct stop st;
+
+    st.st_op = STOFFL;
+    st.st_count = 1;
+
+    return ioctl(fd, STIOCTOP, &st);
+}
+
+#if !defined(HAVE_BROKEN_FSF)
+/*
+ * Forward space the tape device count files.
+ */
+int
+tape_tapefd_fsf(fd, count)
+    int fd, count;
+{
+    struct stop st;
+
+    st.st_op = STFSF;
+    st.st_count = count;
+
+    return ioctl(fd, STIOCTOP, &st);
+}
+#endif
+
+/*
+ * Write some number of end of file marks (a.k.a. tape marks).
+ */
+int
+tape_tapefd_weof(fd, count)
+    int fd, count;
+{
+    struct stop st;
+
+    st.st_op = STWEOF;
+    st.st_count = count;
+
+    return ioctl(fd, STIOCTOP, &st);
+}
+
+#else /* AIX_TAPEIO */                                                 /* }{ */
+#ifdef XENIX_TAPEIO                                                    /* { */
+
+#include <sys/tape.h>
+
+/*
+ * Rewind a tape to the beginning.
+ */
+int
+tape_tapefd_rewind(fd)
+    int fd;
+{
+    int st;
+
+    return ioctl(fd, MT_REWIND, &st);
+}
+
+/*
+ * Rewind and unload a tape.
+ */
+int
+tape_tapefd_unload(fd)
+    int fd;
+{
+    int st;
+    int f;
+
+#ifdef MT_OFFLINE
+    f = MT_OFFLINE;
+#else
+#ifdef MT_UNLOAD
+    f = MT_UNLOAD;
+#else
+    f = syntax error;
+#endif
+#endif
+    return ioctl(fd, f, &st);
+}
+
+#if !defined(HAVE_BROKEN_FSF)
+/*
+ * Forward space the tape device count files.
+ */
+int
+tape_tapefd_fsf(fd, count)
+    int fd, count;
+{
+    int st;
+    int status;
+
+    while (--count >= 0) {
+       if ((status = ioctl(fd, MT_RFM, &st)) != 0) {
+           break;
+       }
+    }
+
+    return status;
+}
+#endif
+
+/*
+ * Write some number of end of file marks (a.k.a. tape marks).
+ */
+int
+tape_tapefd_weof(fd, count)
+    int fd, count;
+{
+    int st;
+    int c;
+    int status;
+
+    while (--count >= 0) {
+       if ((status = ioctl(fd, MT_WFM, &st)) != 0) {
+           break;
+       }
+    }
+
+    return status;
+}
+
+#else  /* ! AIX_TAPEIO && !XENIX_TAPEIO */                             /* }{ */
+
+#include <sys/mtio.h>
+
+/*
+ * Rewind a tape to the beginning.
+ */
+int
+tape_tapefd_rewind(fd)
+    int fd;
+{
+    struct mtop mt;
+    int rc=-1, cnt;
+
+    mt.mt_op = MTREW;
+    mt.mt_count = 1;
+
+    /*
+     * EXB-8200 drive on FreeBSD can fail to rewind, but retrying won't
+     * hurt, and it will usually even work!
+     */
+    for(cnt = 10; cnt >= 0; --cnt) {
+       if ((rc = ioctl(fd, MTIOCTOP, &mt)) == 0) {
+           break;
+       }
+       if (cnt) {
+           sleep(3);
+       }
+    }
+    return rc;
+}
+
+/*
+ * Rewind and unload a tape.
+ */
+int
+tape_tapefd_unload(fd)
+    int fd;
+{
+    struct mtop mt;
+    int rc=-1, cnt;
+
+#ifdef MTUNLOAD
+    mt.mt_op = MTUNLOAD;
+#else
+#ifdef MTOFFL
+    mt.mt_op = MTOFFL;
+#else
+    mt.mt_op = syntax error;
+#endif
+#endif
+    mt.mt_count = 1;
+
+    /*
+     * EXB-8200 drive on FreeBSD can fail to unload, but retrying won't
+     * hurt, and it will usually even work!
+     */
+    for(cnt = 10; cnt >= 0; --cnt) {
+       if ((rc = ioctl(fd, MTIOCTOP, &mt)) == 0) {
+           break;
+       }
+       if (cnt) {
+           sleep(3);
+       }
+    }
+    return rc;
+}
+
+#if !defined(HAVE_BROKEN_FSF)
+/*
+ * Forward space the tape device count files.
+ */
+int
+tape_tapefd_fsf(fd, count)
+    int fd, count;
+{
+    struct mtop mt;
+
+    mt.mt_op = MTFSF;
+    mt.mt_count = count;
+
+    return ioctl(fd, MTIOCTOP, &mt);
+}
+#endif
+
+/*
+ * 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.
+ */
+{
+    struct mtop mt;
+
+    mt.mt_op = MTWEOF;
+    mt.mt_count = count;
+
+    return ioctl(fd, MTIOCTOP, &mt);
+}
+
+#endif /* !XENIX_TAPEIO */                                             /* } */
+#endif /* !AIX_TAPEIO */                                               /* } */
+#endif /* !UWARE_TAPEIO */                                             /* } */
+
+/*
+ * At this point we have pulled in every conceivable #include file :-),
+ * so now come the more general routines with minimal #ifdef-ing.
+ */
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+/*
+ * is_zftape(filename) checks if filename is a valid ftape device name.
+ */
+int
+is_zftape(filename)
+    const char *filename;
+{
+    if (strncmp(filename, "/dev/nftape", 11) == 0) return(1);
+    if (strncmp(filename, "/dev/nqft",    9) == 0) return(1);
+    if (strncmp(filename, "/dev/nrft",    9) == 0) return(1);
+    return(0);
+}
+#endif /* HAVE_LINUX_ZFTAPE_H */
+
+int tape_tape_open(filename, flags, mask)
+    char *filename;
+    int flags;
+    int mask;
+{
+    int ret = 0, delay = 2, timeout = 200;
+
+    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;
+       }
+       timeout -= delay;
+       if (timeout <= 0) {
+           break;
+       }
+       if (delay < 16) {
+           delay *= 2;
+       }
+       sleep(delay);
+    }
+#ifdef HAVE_LINUX_ZFTAPE_H
+    /*
+     * switch the block size for the zftape driver (3.04d)
+     * (its default is 10kb and not TAPE_BLOCK_BYTES=32kb)
+     *        A. Gebhardt <albrecht.gebhardt@uni-klu.ac.at>
+     */
+    if (ret >= 0 && is_zftape(filename) == 1) {
+       struct mtop mt;
+
+       mt.mt_op = MTSETBLK;
+       mt.mt_count = 32 * 1024;        /* wrong?  tape blocksize??? */
+       ioctl(ret, MTIOCTOP, &mt);
+    }
+#endif /* HAVE_LINUX_ZFTAPE_H */
+    return ret;
+}
+
+ssize_t tape_tapefd_read(fd, buffer, count)
+    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;
+{
+    return write(fd, buffer, count);
+}
+
+int tape_tapefd_close(fd)
+    int fd;
+{
+    return close(fd);
+}
+
+void tape_tapefd_resetofs(fd)
+    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);
+}
+
+int
+tape_tapefd_status(fd, stat)
+    int fd;
+    struct am_mt_status *stat;
+{
+    int res = 0;
+    int anything_valid = 0;
+#if defined(MTIOCGET)
+    struct mtget buf;
+#endif
+
+    memset((void *)stat, 0, sizeof(*stat));
+
+#if defined(MTIOCGET)                                                  /* { */
+    res = ioctl(fd,MTIOCGET,&buf);
+
+    if (res >= 0) {
+#ifdef MT_ONL                                                          /* { */
+        /* IRIX-ish system */
+       anything_valid = 1;
+       stat->online_valid = 1;
+       stat->online = (0 != (buf.mt_dposn & MT_ONL));
+       stat->bot_valid = 1;
+       stat->bot = (0 != (buf.mt_dposn & MT_BOT));
+       stat->eot_valid = 1;
+       stat->eot = (0 != (buf.mt_dposn & MT_EOT));
+       stat->protected_valid = 1;
+       stat->protected = (0 != (buf.mt_dposn & MT_WPROT));
+#else                                                                  /* }{ */
+#ifdef GMT_ONLINE                                                      /* { */
+        /* Linux-ish system */
+       anything_valid = 1;
+       stat->online_valid = 1;
+       stat->online = (0 != GMT_ONLINE(buf.mt_gstat));
+       stat->bot_valid = 1;
+       stat->bot = (0 != GMT_BOT(buf.mt_gstat));
+       stat->eot_valid = 1;
+       stat->eot = (0 != GMT_EOT(buf.mt_gstat));
+       stat->protected_valid = 1;
+       stat->protected = (0 != GMT_WR_PROT(buf.mt_gstat));
+#else                                                                  /* }{ */
+#ifdef DEV_BOM                                                         /* { */
+        /* OSF1-ish system */
+       anything_valid = 1;
+       stat->online_valid = 1;
+       stat->online = (0 == (DEV_OFFLINE & buf.mt_dsreg));
+       stat->bot_valid = 1;
+       stat->bot = (0 != (DEV_BOM & buf.mt_dsreg));
+       stat->protected_valid = 1;
+       stat->protected = (0 != (DEV_WRTLCK & buf.mt_dsreg));
+#else                                                                  /* }{ */
+        /* Solaris, minix, etc. */
+       anything_valid = 1;
+       stat->online_valid = 1;
+       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 = (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 = (unsigned long)buf.mt_erreg;
+#endif
+#if defined(HAVE_MT_FLAGS) && defined(MTF_SCSI)                        /* { */
+       /* 
+        * On Solaris, the file/block number fields are only valid if
+        * the driver is SCSI.  And in that case, the dsreg value is
+        * not useful (it is a retry count).
+        */
+       if(buf.mt_flags & MTF_SCSI) {
+           stat->device_status_valid = 0;
+#ifdef HAVE_MT_FILENO
+           stat->fileno_valid = 1;
+           stat->fileno = (long)buf.mt_fileno;
+#endif
+#ifdef HAVE_MT_BLKNO
+           stat->blkno_valid = 1;
+           stat->blkno = (long)buf.mt_blkno;
+#endif
+       }
+#endif                                                                 /* } */
+#endif                                                                 /* } */
+#endif                                                                 /* } */
+#endif                                                                 /* } */
+    }
+#endif                                                                 /* } */
+
+    /*
+     * If we did not find any valid information, do a stat on the device
+     * and if that returns successfully, assume it is at least online.
+     */
+    if(!anything_valid && res == 0) {
+       struct stat sbuf;
+
+       res = fstat(fd, &sbuf);
+       anything_valid = 1;
+       stat->online_valid = 1;
+       stat->online = (res == 0);
+    }
+
+    return res;
+}
+
+int tape_tape_stat(filename, buf)
+     char *filename;
+     struct stat *buf;
+{
+     return stat(filename, buf);
+}
+
+int tape_tape_access(filename, mode)
+     char *filename;
+     int mode;
+{
+     return access(filename, mode);
+}
+
+int 
+tape_tapefd_can_fork(fd)
+    int fd;
+{
+    return 1;
+}
+
diff --git a/tape-src/output-tape.h b/tape-src/output-tape.h
new file mode 100644 (file)
index 0000000..1aa9fee
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+
+/*
+ * $Id: output-tape.h,v 1.1.2.2.2.2 2003/03/06 21:44:21 martinea Exp $
+ *
+ * tapeio.c virtual tape interface for normal tape drives.
+ */
+
+#ifndef OUTPUT_TAPE_H
+#define OUTPUT_TAPE_H
+
+#ifdef NO_AMANDA
+#include "output-rait.h"
+#else
+#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));
+
+#endif /* OUTPUT_TAPE_H */
diff --git a/tape-src/tapeio.c b/tape-src/tapeio.c
new file mode 100644 (file)
index 0000000..984dddc
--- /dev/null
@@ -0,0 +1,1518 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+
+/*
+ * $Id: tapeio.c,v 1.20.4.7.4.4.2.9 2003/11/28 12:34:52 martinea Exp $
+ *
+ * implements generic tape I/O functions
+ */
+
+#include "amanda.h"
+#include <errno.h>
+
+#include "tapeio.h"
+#include "fileheader.h"
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#endif
+
+#include "output-tape.h"
+#include "output-null.h"
+#include "output-rait.h"
+#include "output-file.h"
+
+static struct virtualtape {
+    char *prefix;
+    int (*xxx_tape_access) P((char *, int));
+    int (*xxx_tape_open) ();
+    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));
+} vtable[] = {
+  /* note: "tape" has to be the first entry because it is the
+  **        default if no prefix match is found.
+  */
+  {"tape", tape_tape_access, tape_tape_open, tape_tape_stat,
+       tape_tapefd_close, tape_tapefd_fsf,
+       tape_tapefd_read, tape_tapefd_rewind, tape_tapefd_resetofs,
+       tape_tapefd_unload, tape_tapefd_status, tape_tapefd_weof,
+        tape_tapefd_write, tape_tapefd_can_fork },
+  {"null", null_tape_access, null_tape_open, null_tape_stat,
+       null_tapefd_close, null_tapefd_fsf,
+       null_tapefd_read, null_tapefd_rewind, null_tapefd_resetofs,
+       null_tapefd_unload, null_tapefd_status, null_tapefd_weof,
+        null_tapefd_write, null_tapefd_can_fork },
+  {"rait", rait_access, rait_tape_open, rait_stat,
+       rait_close, rait_tapefd_fsf,
+       rait_read, rait_tapefd_rewind, rait_tapefd_resetofs,
+       rait_tapefd_unload, rait_tapefd_status, rait_tapefd_weof,
+        rait_write, rait_tapefd_can_fork },
+  {"file", file_tape_access, file_tape_open, file_tape_stat,
+       file_tapefd_close, file_tapefd_fsf,
+       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,},
+};
+
+static struct tape_info {
+    int vtape_index;
+    char *host;
+    char *disk;
+    int level;
+    char *datestamp;
+    long length;
+    char *tapetype;
+    int fake_label;
+    int ioctl_fork;
+    int master_fd;
+} *tape_info = NULL;
+static int tape_info_count = 0;
+
+static char *errstr = NULL;
+
+/*
+ * Additional initialization function for tape_info table.
+ */
+
+static void
+tape_info_init(ptr)
+    void *ptr;
+{
+    struct tape_info *t = ptr;
+
+    t->level = -1;
+    t->vtape_index = -1;
+    t->ioctl_fork = 1;
+    t->master_fd = -1;
+}
+
+/*
+ * Convert the "name" part of a device to a vtape slot.
+ */
+
+static int
+name2slot(name, ntrans)
+    char *name;
+    char **ntrans;
+{
+    char *pc;
+    int len, i;
+
+    if(0 != (pc = strchr(name, ':'))) {
+        len = 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]) {
+               *ntrans = pc + 1;
+               return i;
+            }
+        }
+    }
+    *ntrans = name;
+    return 0;
+}
+
+/*
+ * Routines for parsing a device name.
+ */
+
+/*
+ * Initialize parsing.  The text in the "dev" parameter will be altered,
+ * so a copy should be passed to us.
+ */
+
+int
+tapeio_init_devname(char * dev,
+                   char **dev_left,
+                   char **dev_right,
+                   char **dev_next) {
+    int ch;
+    char *p;
+    int depth;
+
+    *dev_left = *dev_right = *dev_next = NULL; /* defensive coding */
+
+    /*
+     * See if there is a '{' and find the matching '}'.
+     */
+    if((*dev_next = p = strchr(dev, '{')) != NULL) {
+       depth = 1;
+       p++;
+       while(depth > 0) {
+           while((ch = *p++) != '\0' && ch != '{' && ch != '}') {}
+           if(ch == '\0') {
+               /*
+                * Did not find a matching '}'.
+                */
+               amfree(dev);
+               errno = EINVAL;
+               return -1;
+           } else if(ch == '{') {
+               depth++;
+           } else if(ch == '}') {
+               depth--;
+           }
+       }
+       if(strchr(p, '{') != NULL || strchr(p, '}') != NULL) {
+           amfree(dev);
+           errno = EINVAL;
+           return -1;                          /* only one list allowed */
+       }
+       *dev_left = dev;                        /* text before the '{' */
+       **dev_next = '\0';                      /* zap the '{' */
+       (*dev_next)++;                          /* point to the first name */
+       p[-1] = '\0';                           /* zap the '}' */
+       *dev_right = p;                         /* text after the '}' */
+    } else {
+       /*
+        * Arrange to return just one name.
+        */
+       *dev_next = dev;
+       *dev_left = *dev_right = "";
+    }
+    return 0;
+}
+
+/*
+ * Return the next device name.  A dynamic area is returned that the
+ * caller is responsible for freeing.
+ */
+
+char *
+tapeio_next_devname(char * dev_left,
+                   char * dev_right,
+                   char **dev_next) {
+    int ch;
+    char *next;
+    char *p;
+    int depth;
+
+    p = next = *dev_next;                      /* remember the start point */
+    depth = 0;
+    do {
+       while((ch = *p++) != '\0' && ch != '{' && ch != '}' && ch != ',') {}
+       if(ch == '\0') {
+           /*
+            * Found the end of a name.
+            */
+           assert(depth == 0);
+           if(*next == '\0') {
+               return NULL;                    /* end of the list */
+           }
+           p--;                                /* point to the null byte */
+           break;
+       } else if(ch == '{') {
+           depth++;
+       } else if(ch == '}') {
+           assert(depth > 0);
+           depth--;
+       }
+    } while(depth != 0 || ch != ',');
+    if(ch == ',') {
+       p[-1] = '\0';                           /* zap the ',' */
+    }
+    *dev_next = p;                             /* set up for the next call */
+    return vstralloc(dev_left, next, dev_right, NULL);
+}
+
+/*
+ * The following functions get/set fields in the tape_info structure.
+ * To allow them to be called (e.g. set) from lower level open functions
+ * started by tape_open, we check and allocate the tape_info structure
+ * here as well as in tape_open.
+ */
+
+char *
+tapefd_getinfo_host(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    if(tape_info[fd].master_fd != -1)
+       return tapefd_getinfo_host(tape_info[fd].master_fd);
+    return tape_info[fd].host;
+}
+
+void
+tapefd_setinfo_host(fd, v)
+    int fd;
+    char *v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    amfree(tape_info[fd].host);
+    if(v) {
+       tape_info[fd].host = stralloc(v);
+    }
+}
+
+char *
+tapefd_getinfo_disk(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    if(tape_info[fd].master_fd != -1)
+       return tapefd_getinfo_disk(tape_info[fd].master_fd);
+    return tape_info[fd].disk;
+}
+
+void
+tapefd_setinfo_disk(fd, v)
+    int fd;
+    char *v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    amfree(tape_info[fd].disk);
+    if(v) {
+       tape_info[fd].disk = stralloc(v);
+    }
+}
+
+int
+tapefd_getinfo_level(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    if(tape_info[fd].master_fd != -1)
+       return tapefd_getinfo_level(tape_info[fd].master_fd);
+    return tape_info[fd].level;
+}
+
+void
+tapefd_setinfo_level(fd, v)
+    int fd;
+    int v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    tape_info[fd].level = v;
+}
+
+char *
+tapefd_getinfo_datestamp(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    return tape_info[fd].datestamp;
+}
+
+void
+tapefd_setinfo_datestamp(fd, v)
+    int fd;
+    char *v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    tape_info[fd].datestamp = newstralloc(tape_info[fd].datestamp, v);
+}
+
+long
+tapefd_getinfo_length(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    return tape_info[fd].length;
+}
+
+void
+tapefd_setinfo_length(fd, v)
+    int fd;
+    long v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    tape_info[fd].length = v;
+}
+
+char *
+tapefd_getinfo_tapetype(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    return tape_info[fd].tapetype;
+}
+
+void
+tapefd_setinfo_tapetype(fd, v)
+    int fd;
+    char *v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    tape_info[fd].tapetype = newstralloc(tape_info[fd].tapetype, v);
+}
+
+int
+tapefd_getinfo_fake_label(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    return tape_info[fd].fake_label;
+}
+
+void
+tapefd_setinfo_fake_label(fd, v)
+    int fd;
+    int v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    tape_info[fd].fake_label = v;
+}
+
+int
+tapefd_getinfo_ioctl_fork(fd)
+    int fd;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    return tape_info[fd].ioctl_fork;
+}
+
+void
+tapefd_setinfo_ioctl_fork(fd, v)
+    int fd;
+    int v;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 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;
+{
+    amtable_alloc((void **)&tape_info,
+                 &tape_info_count,
+                 sizeof(*tape_info),
+                 fd + 1,
+                 10,
+                 tape_info_init);
+    tape_info[fd].master_fd = master_fd;
+}
+
+
+/*
+ * The normal tape operation functions.
+ */
+
+int
+tape_access(filename, mode)
+    char *filename;
+    int mode;
+{
+    char *tname;
+    int vslot;
+
+    vslot = name2slot(filename, &tname);
+    return vtable[vslot].xxx_tape_access(tname, mode);
+}
+
+int
+tape_stat(filename, buf)
+    char *filename;
+    struct stat *buf;
+{
+    char *tname;
+    int vslot;
+
+    vslot = name2slot(filename, &tname);
+    return vtable[vslot].xxx_tape_stat(tname, buf);
+}
+
+int
+tape_open(filename, mode, mask)
+    char *filename;
+    int mode;
+    int mask;
+{
+    char *tname;
+    int vslot;
+    int fd;
+
+    vslot = name2slot(filename, &tname);
+    if((fd = vtable[vslot].xxx_tape_open(tname, mode, mask)) >= 0) {
+       amtable_alloc((void **)&tape_info,
+                     &tape_info_count,
+                     sizeof(*tape_info),
+                     fd + 1,
+                     10,
+                     tape_info_init);
+       /*
+        * It is possible to recurse in the above open call and come
+        * back here twice for the same file descriptor.  Set the vtape
+        * index only if it is not already set, i.e. the first call wins.
+        */
+       if(tape_info[fd].vtape_index < 0) {
+           tape_info[fd].vtape_index = vslot;
+       }
+    }
+    return fd;
+}
+
+int
+tapefd_close(fd)
+    int fd;
+{
+    int vslot, res = -1;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    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));
+        tape_info_init((void *)(tape_info + fd));
+    }
+    return res;
+}
+
+int
+tapefd_can_fork(fd)
+    int fd;
+{
+    int vslot, res = -1;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    res = vtable[vslot].xxx_tapefd_can_fork(fd);
+
+    return res;
+}
+
+int
+tapefd_fsf(fd, count)
+    int fd;
+    int count;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    return vtable[vslot].xxx_tapefd_fsf(fd, count);
+}
+
+int
+tapefd_rewind(fd)
+    int fd;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    return vtable[vslot].xxx_tapefd_rewind(fd);
+}
+
+void
+tapefd_resetofs(fd)
+    int fd;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;                          /* not that it matters */
+       return;
+    }
+    vtable[vslot].xxx_tapefd_resetofs(fd);
+}
+
+int
+tapefd_unload(fd)
+    int fd;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    return vtable[vslot].xxx_tapefd_unload(fd);
+}
+
+int
+tapefd_status(fd, stat)
+    int fd;
+    struct am_mt_status *stat;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    return vtable[vslot].xxx_tapefd_status(fd, stat);
+}
+
+int
+tapefd_weof(fd, count)
+    int fd;
+    int count;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    return vtable[vslot].xxx_tapefd_weof(fd, count);
+}
+
+ssize_t
+tapefd_read(fd, buffer, count)
+    int fd;
+    void *buffer;
+    size_t count;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    return vtable[vslot].xxx_tapefd_read(fd, buffer, count);
+}
+
+ssize_t
+tapefd_write(fd, buffer, count)
+    int fd;
+    const void *buffer;
+    size_t count;
+{
+    int vslot;
+
+    if(fd < 0
+       || fd >= tape_info_count
+       || (vslot = tape_info[fd].vtape_index) < 0) {
+       errno = EBADF;
+       return -1;
+    }
+    return vtable[vslot].xxx_tapefd_write(fd, buffer, count);
+}
+
+char *
+tape_rewind(devname)
+    char *devname;
+{
+    int fd;
+    char *r = NULL;
+
+    if((fd = tape_open(devname, O_RDONLY)) < 0) {
+       r = errstr = newvstralloc(errstr,
+                                 "tape_rewind: tape open: ",
+                                 devname,
+                                 ": ",
+                                 strerror(errno),
+                                 NULL);
+    } else if(tapefd_rewind(fd) == -1) {
+       r = errstr = newvstralloc(errstr,
+                                 "tape_rewind: rewinding tape: ",
+                                 devname,
+                                 ": ",
+                                 strerror(errno),
+                                 NULL);
+    }
+    if(fd >= 0) {
+       tapefd_close(fd);
+    }
+    return r;
+}
+
+char *
+tape_unload(devname)
+    char *devname;
+{
+    int fd;
+    char *r = NULL;
+
+    if((fd = tape_open(devname, O_RDONLY)) < 0) {
+       r = errstr = newvstralloc(errstr,
+                                 "tape_unload: tape open: ",
+                                 devname,
+                                 ": ",
+                                 strerror(errno),
+                                 NULL);
+    } else if(tapefd_unload(fd) == -1) {
+       r = errstr = newvstralloc(errstr,
+                                 "tape_unload: unloading tape: ",
+                                 devname,
+                                 ": ",
+                                 strerror(errno),
+                                 NULL);
+    }
+    if(fd >= 0) {
+       tapefd_close(fd);
+    }
+    return r;
+}
+
+char *
+tape_fsf(devname, count)
+    char *devname;
+    int count;
+{
+    int fd;
+    char count_str[NUM_STR_SIZE];
+    char *r = NULL;
+
+    if((fd = tape_open(devname, O_RDONLY)) < 0) {
+       r = errstr = newvstralloc(errstr,
+                                 "tape_fsf: tape open: ",
+                                 devname,
+                                 ": ",
+                                 strerror(errno),
+                                 NULL);
+    } else if(tapefd_fsf(fd, count) == -1) {
+       ap_snprintf(count_str, sizeof(count_str), "%d", count);
+       r = errstr = newvstralloc(errstr,
+                                 "tape_fsf: fsf ",
+                                 count_str,
+                                 "file", (count == 1) ? "" : "s",
+                                 ": ",
+                                 strerror(errno),
+                                 NULL);
+    }
+    if(fd >= 0) {
+       tapefd_close(fd);
+    }
+    return r;
+}
+
+char *
+tapefd_rdlabel(fd, datestamp, label)
+    int fd;
+    char **datestamp;
+    char **label;
+{
+    int rc;
+    size_t buflen;
+    char *buffer = NULL;
+    dumpfile_t file;
+    char *r = NULL;
+
+    amfree(*datestamp);
+    amfree(*label);
+    buflen = MAX_TAPE_BLOCK_BYTES;
+    buffer = alloc(buflen + 1);
+
+    if(tapefd_getinfo_fake_label(fd)) {
+       *datestamp = stralloc("X");
+       *label = stralloc(FAKE_LABEL);
+    } else if(tapefd_rewind(fd) == -1) {
+       r = errstr = newstralloc2(errstr, "rewinding tape: ", strerror(errno));
+    } else if((rc = tapefd_read(fd, buffer, buflen)) == -1) {
+       r = errstr = newstralloc2(errstr, "reading label: ", strerror(errno));
+    } else {
+
+       /* make sure buffer is null-terminated */
+       buffer[rc] = '\0';
+
+       parse_file_header(buffer, &file, rc);
+       if(file.type != F_TAPESTART) {
+           r = errstr = newstralloc(errstr, "not an amanda tape");
+       } else {
+           *datestamp = stralloc(file.datestamp);
+           *label = stralloc(file.name);
+       }
+    }
+    amfree(buffer);
+    return r;
+}
+
+char *
+tape_rdlabel(devname, datestamp, label)
+    char *devname;
+    char **datestamp;
+    char **label;
+{
+    int fd;
+    char *r = NULL;
+
+    if((fd = tape_open(devname, O_RDONLY)) < 0) {
+       r = errstr = newvstralloc(errstr,
+                                 "tape_rdlabel: tape open: ",
+                                 devname,
+                                 ": ",
+                                 strerror(errno),
+                                 NULL);
+    } else if(tapefd_rdlabel(fd, datestamp, label) != NULL) {
+       r = errstr;
+    }
+    if(fd >= 0) {
+       tapefd_close(fd);
+    }
+    return r;
+}
+
+char *
+tapefd_wrlabel(fd, datestamp, label, size)
+    int fd;
+    char *datestamp;
+    char *label;
+    unsigned int size;
+{
+    int rc;
+    char *buffer = NULL;
+    dumpfile_t file;
+    char *r = NULL;
+
+    if(tapefd_rewind(fd) == -1) {
+       r = errstr = newstralloc2(errstr, "rewinding tape: ", strerror(errno));
+    } 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';
+       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) {
+           r = errstr = newstralloc2(errstr,
+                                     "writing label: ",
+                                     (rc != -1) ? "short write"
+                                                : strerror(errno));
+       }
+       amfree(buffer);
+    }
+    return r;
+}
+
+char *
+tape_wrlabel(devname, datestamp, label, size)
+    char *devname;
+    char *datestamp;
+    char *label;
+    unsigned int size;
+{
+    int fd;
+    char *r = NULL;
+
+    if((fd = tape_open(devname, O_WRONLY)) < 0) {
+       r = errstr = newstralloc2(errstr,
+                                 "writing label: ",
+                                 (errno == EACCES) ? "tape is write-protected"
+                                                   : strerror(errno));
+    } else if(tapefd_wrlabel(fd, datestamp, label, size) != NULL) {
+       r = errstr;
+    }
+    if(fd >= 0) {
+       tapefd_close(fd);
+    }
+    return r;
+}
+
+char *
+tapefd_wrendmark(fd, datestamp, size)
+    int fd;
+    char *datestamp;
+    unsigned int size;
+{
+    int 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';
+    buffer = alloc(size);
+    file.blocksize = size;
+    build_header(buffer, &file, size);
+    tapefd_setinfo_host(fd, NULL);
+    tapefd_setinfo_disk(fd, "TAPEEND");
+    tapefd_setinfo_level(fd, -1);
+
+    if((rc = tapefd_write(fd, buffer, size)) != size) {
+       r = errstr = newstralloc2(errstr, "writing endmark: ",
+                                 (rc != -1) ? "short write" : strerror(errno));
+    }
+    amfree(buffer);
+
+    return r;
+}
+
+char *
+tape_wrendmark(devname, datestamp, size)
+    char *devname;
+    char *datestamp;
+    unsigned int size;
+{
+    int fd;
+    char *r = NULL;
+
+    if((fd = tape_open(devname, O_WRONLY)) < 0) {
+       r = errstr = newstralloc2(errstr,
+                                 "writing endmark: ",
+                                 (errno == EACCES) ? "tape is write-protected"
+                                                   : strerror(errno));
+    } else if(tapefd_wrendmark(fd, datestamp, size) != NULL) {
+       r = errstr;
+    }
+    if(fd >= 0) {
+       tapefd_close(fd);
+    }
+    return r;
+}
+
+char *
+tape_writable(devname)
+    char *devname;
+{
+    int fd = -1;
+    char *r = NULL;
+
+    /* first, make sure the file exists and the permissions are right */
+
+    if(tape_access(devname, R_OK|W_OK) == -1) {
+       r = errstr = newstralloc(errstr, strerror(errno));
+    } else if((fd = tape_open(devname, O_WRONLY)) < 0) {
+       r = errstr = newstralloc(errstr,
+                                (errno == EACCES) ? "tape write-protected"
+                                                  : strerror(errno));
+    }
+    if(fd >= 0) {
+       tapefd_close(fd);
+    }
+    return r;
+}
+
+#ifdef TEST
+
+/*
+ * The following test program may be used to exercise I/O patterns through
+ * the tapeio interface.  Commands may either be on the command line or
+ * read from stdin (e.g. for a test suite).
+ */
+
+#include "token.h"
+
+#if USE_RAND
+/* If the C library does not define random(), try to use rand() by
+   defining USE_RAND, but then make sure you are not using hardware
+   compression, because the low-order bits of rand() may not be that
+   random... :-( */
+#define random() rand()
+#define srandom(seed) srand(seed)
+#endif
+
+static char *pgm;
+
+static void
+do_help()
+{
+    fprintf(stderr, "  ?|help\n");
+    fprintf(stderr, "  open [\"file\"|$TAPE [\"mode\":O_RDONLY]]\n");
+    fprintf(stderr, "  read [\"records\":\"all\"]\n");
+    fprintf(stderr, "  write [\"records\":1] [\"file#\":\"+\"] [\"record#\":\"+\"] [\"host\"] [\"disk\"] [\"level\"]\n");
+    fprintf(stderr, "  eof|weof [\"count\":1]\n");
+    fprintf(stderr, "  fsf [\"count\":1]\n");
+    fprintf(stderr, "  rewind\n");
+    fprintf(stderr, "  unload\n");
+}
+
+static void
+usage()
+{
+    fprintf(stderr, "usage: %s [-c cmd [args] [%% cmd [args] ...]]\n", pgm);
+    do_help();
+}
+
+#define TEST_BLOCKSIZE (32 * 1024)
+
+#define MAX_TOKENS     10
+
+extern int optind;
+
+static char *token_area[MAX_TOKENS + 1];
+static char **token;
+static int token_count;
+
+static int fd = -1;
+static int current_file = 0;
+static int current_record = 0;
+
+static int have_length = 0;
+static int length = 0;
+
+static int show_timestamp = 0;
+
+char write_buf[TEST_BLOCKSIZE];
+
+static void
+do_open()
+{
+    int mode;
+    char *file;
+
+    if(token_count < 2
+       || (token_count >= 2 && strcmp(token[1], "$TAPE") == 0)) {
+       if((file = getenv("TAPE")) == NULL) {
+           fprintf(stderr, "tape_open: no file name and $TAPE not set\n");
+           return;
+       }
+    } else {
+       file = token[1];
+    }
+    if(token_count > 2) {
+       mode = atoi(token[2]);
+    } else {
+       mode = O_RDONLY;
+    }
+
+    fprintf(stderr, "tapefd_open(\"%s\", %d): ", file, mode);
+    if((fd = tape_open(file, mode, 0644)) < 0) {
+       perror("");
+    } else {
+       fprintf(stderr, "%d (OK)\n", fd);
+       if(have_length) {
+           tapefd_setinfo_length(fd, length);
+       }
+    }
+}
+
+static void
+do_close()
+{
+    int result;
+
+    fprintf(stderr, "tapefd_close(): ");
+    if((result = tapefd_close(fd)) < 0) {
+       perror("");
+    } else {
+       fprintf(stderr, "%d (OK)\n", result);
+    }
+}
+
+static void
+do_read()
+{
+    int result;
+    int count = 0;
+    int have_count = 0;
+    char buf[sizeof(write_buf)];
+    int *p;
+    int i;
+    char *s;
+    time_t then;
+    struct tm *tm;
+
+    if(token_count > 1 && strcmp(token[1], "all") != 0) {
+       count = 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) {
+           perror("");
+           break;
+       } else if(result == 0) {
+           fprintf(stderr, "%d (EOF)\n", result);
+           /*
+            * If we were not given a count, EOF breaks the loop, otherwise
+            * we keep trying (to test read after EOF handling).
+            */
+           if(! have_count) {
+               break;
+           }
+       } else {
+           if(result == sizeof(buf)) {
+               s = "OK";
+           } else {
+               s = "short read";
+           }
+
+           /*
+            * If the amount read is really short, we may refer to junk
+            * when displaying the record data, but things are pretty
+            * well screwed up at this point anyway so it is not worth
+            * the effort to deal with.
+            */
+           fprintf(stderr,
+                   "%d (%s): file %d: record %d",
+                   result,
+                   s,
+                   p[0],
+                   p[1]);
+           if(show_timestamp) {
+               then = p[2];
+               tm = localtime(&then);
+               fprintf(stderr,
+                       ": %04d/%02d/%02d %02d:%02d:%02d\n",
+                       tm->tm_year + 1900,
+                       tm->tm_mon + 1,
+                       tm->tm_mday,
+                       tm->tm_hour,
+                       tm->tm_min,
+                       tm->tm_sec);
+           }
+           fputc('\n', stderr);
+       }
+    }
+}
+
+static void
+do_write()
+{
+    int result;
+    int count;
+    int *p;
+    int i;
+    char *s;
+    time_t now;
+    struct tm *tm;
+
+    if(token_count > 1) {
+       count = atoi(token[1]);
+    } else {
+       count = 1;
+    }
+
+    if(token_count > 2 && strcmp(token[2], "+") != 0) {
+       current_file = atoi(token[2]);
+    }
+
+    if(token_count > 3 && strcmp(token[3], "+") != 0) {
+       current_record = atoi(token[3]);
+    }
+
+    if(token_count > 4 && token[4][0] != '\0') {
+       tapefd_setinfo_host(fd, token[4]);
+    }
+
+    if(token_count > 5 && token[5][0] != '\0') {
+       tapefd_setinfo_disk(fd, token[5]);
+    }
+
+    if(token_count > 6 && token[6][0] != '\0') {
+       tapefd_setinfo_level(fd, atoi(token[6]));
+    }
+
+    p = (int *)write_buf;
+    time(&now);
+    p[2] = now;
+    tm = localtime(&now);
+    for(i = 0; i < count; i++, current_record++) {
+       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) {
+           perror("");
+           break;
+       } else {
+           if(result == sizeof(write_buf)) {
+               s = "OK";
+           } else {
+               s = "short write";
+           }
+           fprintf(stderr,
+                   "%d (%s): file %d: record %d",
+                   result,
+                   s,
+                   p[0],
+                   p[1]);
+           if(show_timestamp) {
+               fprintf(stderr,
+                       ": %04d/%02d/%02d %02d:%02d:%02d\n",
+                       tm->tm_year + 1900,
+                       tm->tm_mon + 1,
+                       tm->tm_mday,
+                       tm->tm_hour,
+                       tm->tm_min,
+                       tm->tm_sec);
+           }
+           fputc('\n', stderr);
+       }
+    }
+}
+
+static void
+do_fsf()
+{
+    int result;
+    int count;
+
+    if(token_count > 1) {
+       count = atoi(token[1]);
+    } else {
+       count = 1;
+    }
+
+    fprintf(stderr, "tapefd_fsf(%d): ", count);
+    if((result = tapefd_fsf(fd, count)) < 0) {
+       perror("");
+    } else {
+       fprintf(stderr, "%d (OK)\n", result);
+       current_file += count;
+       current_record = 0;
+    }
+}
+
+static void
+do_weof()
+{
+    int result;
+    int count;
+
+    if(token_count > 1) {
+       count = atoi(token[1]);
+    } else {
+       count = 1;
+    }
+
+    fprintf(stderr, "tapefd_weof(%d): ", count);
+    if((result = tapefd_weof(fd, count)) < 0) {
+       perror("");
+    } else {
+       fprintf(stderr, "%d (OK)\n", result);
+       current_file += count;
+       current_record = 0;
+    }
+}
+
+static void
+do_rewind()
+{
+    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;
+    }
+}
+
+static void
+do_unload()
+{
+    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;
+    }
+}
+
+struct cmd {
+    char *name;
+    int min_chars;
+    void (*func)();
+} cmd[] = {
+    { "?",             0,      do_help },
+    { "help",          0,      do_help },
+    { "eof",           0,      do_weof },
+    { "weof",          0,      do_weof },
+    { "fsf",           0,      do_fsf },
+    { "rewind",                0,      do_rewind },
+    { "offline",       0,      do_unload },
+    { "open",          0,      do_open },
+    { "close",         0,      do_close },
+    { "read",          0,      do_read },
+    { "write",         0,      do_write },
+    { NULL,            0,      NULL }
+};
+
+int
+main(argc, argv)
+    int argc;
+    char **argv;
+{
+    int ch;
+    int cmdline = 0;
+    char *line = NULL;
+    char *s;
+    int i;
+    int j;
+    time_t now;
+
+    if((pgm = strrchr(argv[0], '/')) != NULL) {
+       pgm++;
+    } else {
+       pgm = argv[0];
+    }
+
+    /*
+     * Compute the minimum abbreviation for each command.
+     */
+    for(i = 0; cmd[i].name; i++) {
+       cmd[i].min_chars = 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)) {
+                   break;
+               }
+           }
+           if(0 == cmd[j].name) {
+               break;
+           }
+           cmd[i].min_chars++;
+       }
+    }
+
+    /*
+     * Process the command line flags.
+     */
+    while((ch = getopt(argc, argv, "hcl:t")) != EOF) {
+       switch (ch) {
+       case 'c':
+           cmdline = 1;
+           break;
+       case 'l':
+           have_length = 1;
+           length = 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;
+               }
+           } else {
+               length /= 1024;
+           }
+           break;
+       case 't':
+           show_timestamp = 1;
+           break;
+       case 'h':
+       default:
+           usage();
+           return 1;
+       }
+    }
+
+    /*
+     * Initialize the write buffer.
+     */
+    time(&now);
+    srandom(now);
+    for(j = 0; j < sizeof(write_buf); j++) {
+       write_buf[j] = (char)random();
+    }
+
+    /*
+     * Do the tests.
+     */
+    token = token_area + 1;
+    token_area[0] = "";                                /* if cmdline */
+    while(1) {
+       if(cmdline) {
+           for(token_count = 1;
+               token_count < (sizeof(token_area) / sizeof(token_area[0]))
+               && optind < argc;
+               token_count++, optind++) {
+               if(strcmp(argv[optind], "%") == 0) {
+                   optind++;
+                   break;
+               }
+               token_area[token_count] = argv[optind];
+           }
+           token_count--;
+           if(token_count == 0 && optind >= argc) {
+               break;
+           }
+       } else {
+           if((line = areads(0)) == NULL) {
+               break;
+           }
+           if((s = strchr(line, '#')) != NULL) {
+               *s = '\0';
+           }
+           s = line + strlen(line) - 1;
+           while(s >= line && isspace(*s)) {
+               *s-- = '\0';
+           }
+           token_count = split(line,
+                               token_area,
+                               sizeof(token_area) / sizeof(token_area[0]),
+                               " ");
+       }
+       amfree(line);
+
+       /*
+        * Truncate tokens at first comment indicator, then test for
+        * empty command.
+        */
+       for(i = 0; i < token_count; i++) {
+           if(token[i][0] == '#') {
+               token_count = i;
+               break;
+           }
+       }
+       if(token_count <= 0) {
+           continue;                           /* blank/comment input line */
+       }
+
+       /*
+        * Find the command to run, the do it.
+        */
+       j = strlen(token[0]);
+       for(i = 0; cmd[i].name; i++) {
+           if(strncmp(cmd[i].name, token[0], j) == 0
+              && j >= cmd[i].min_chars) {
+               break;
+           }
+       }
+       if(cmd[i].name == NULL) {
+           fprintf(stderr, "%s: unknown command: %s\n", pgm, token[0]);
+           exit(1);
+       }
+       (*cmd[i].func)();
+    }
+
+    return 0;
+}
+
+#endif /* TEST */
diff --git a/tape-src/tapeio.h b/tape-src/tapeio.h
new file mode 100644 (file)
index 0000000..c378319
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: tapeio.h,v 1.9.2.2.4.3.2.3 2003/03/07 20:55:37 martinea Exp $
+ *
+ * interface for tapeio.c
+ */
+#ifndef TAPEIO_H
+#define TAPEIO_H
+
+#include "amanda.h"
+
+/*
+ * Tape drive status structure.  This abstracts the things we are
+ * interested in from the free-for-all of what the various drivers
+ * supply.
+ */
+
+struct am_mt_status {
+    char online_valid;                 /* is the online flag valid? */
+    char bot_valid;                    /* is the BOT flag valid? */
+    char eot_valid;                    /* is the EOT flag valid? */
+    char protected_valid;              /* is the protected flag valid? */
+    char flags_valid;                  /* is the flags field valid? */
+    char fileno_valid;                 /* is the fileno field valid? */
+    char blkno_valid;                  /* is the blkno field valid? */
+    char device_status_valid;          /* is the device status field valid? */
+    char error_status_valid;           /* is the device status field valid? */
+
+    char online;                       /* true if device is online/ready */
+    char bot;                          /* true if tape is at the beginning */
+    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 */
+    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 */
+    unsigned long error_status;                /* "error status", whatever that is */
+};
+
+#define        FAKE_LABEL      "[fake-label]"
+
+int tape_open ();
+
+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_status P((int tapefd, struct am_mt_status *));
+
+void tapefd_resetofs P((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));
+
+char *tapefd_rdlabel P((int tapefd, char **datestamp, char **label));
+char *tapefd_wrlabel P((int tapefd,
+                       char  *datestamp,
+                       char  *label,
+                       unsigned int s));
+char *tapefd_wrendmark P((int tapefd, char *datestamp, unsigned int 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));
+
+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  *datestamp,
+                     char  *label,
+                     unsigned int size));
+char *tape_wrendmark P((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));
+
+#ifdef HAVE_LINUX_ZFTAPE_H
+int is_zftape P((const char *filename));
+#endif
+
+int tapeio_init_devname P((char * dev,
+                          char **dev_left,
+                          char **dev_right,
+                          char **dev_next));
+char *tapeio_next_devname P((char * dev_left,
+                            char * dev_right,
+                            char **dev_next));
+
+#endif /* ! TAPEIO_H */
diff --git a/tape-src/tapetype.c b/tape-src/tapetype.c
new file mode 100644 (file)
index 0000000..9c955a3
--- /dev/null
@@ -0,0 +1,564 @@
+/*
+ * Amanda, The Advanced Maryland Automatic Network Disk Archiver
+ * Copyright (c) 1991-1998 University of Maryland at College Park
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of U.M. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  U.M. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: James da Silva, Systems Design and Analysis Group
+ *                        Computer Science Department
+ *                        University of Maryland at College Park
+ */
+/*
+ * $Id: tapetype.c,v 1.3.2.3.4.3.2.9 2003/11/28 12:34:52 martinea Exp $
+ *
+ * tests a tape in a given tape unit and prints a tapetype entry for
+ * it.  */
+#include "amanda.h"
+
+#include "tapeio.h"
+
+#define NBLOCKS 32                     /* number of random blocks */
+
+extern int optind;
+
+static char *sProgName;
+static char *tapedev;
+static int fd;
+
+static int blockkb = 32;
+static int blocksize;
+
+static char *randombytes = (char *) NULL;
+
+#if USE_RAND
+/* If the C library does not define random(), try to use rand() by
+   defining USE_RAND, but then make sure you are not using hardware
+   compression, because the low-order bits of rand() may not be that
+   random... :-( */
+#define random() rand()
+#define srandom(seed) srand(seed)
+#endif
+
+static void allocrandombytes() {
+  int i, j, page_size;
+  char *p;
+
+  if (randombytes == (char *)NULL) {
+#if defined(HAVE_GETPAGESIZE)
+    page_size = getpagesize();
+#else
+    page_size = 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 */
+    if(i != 0) {
+      randombytes = p + page_size - i;         /* round up to page boundary */
+    } else {
+      randombytes = p;                         /* alloc already on boundary */
+    }
+  }
+}
+
+static void initnotrandombytes() {
+  int i, j;
+  char *p;
+
+  allocrandombytes();
+  j =NBLOCKS * blocksize;
+  p = randombytes;
+  for(i=0; i < j; ++i) {
+    *p++ = (char) (i % 256);
+  }
+}
+
+static void initrandombytes() {
+  int i, j;
+  char *p;
+
+  allocrandombytes();
+  j = NBLOCKS * blocksize;
+  p = randombytes;
+  for(i=0; i < j; ++i) {
+    *p++ = (char)random();
+  }
+}
+
+static char *getrandombytes() {
+  static int counter = 0;
+
+  return randombytes + ((counter++ % NBLOCKS) * blocksize);
+}
+
+static int short_write;
+
+int writeblock(fd)
+     int fd;
+{
+  size_t w;
+
+  if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == blocksize) {
+    return 1;
+  }
+  if (w >= 0) {
+    short_write = 1;
+  } else {
+    short_write = 0;
+  }
+  return 0;
+}
+
+
+/* returns number of blocks actually written */
+size_t writeblocks(int fd, size_t nblks)
+{
+  size_t blks = 0;
+
+  while (blks < nblks) {
+    if (! writeblock(fd)) {
+      return 0;
+    }
+    blks++;
+  }
+
+  return blks;
+}
+
+
+void usage()
+{
+  fputs("usage: ", stderr);
+  fputs(sProgName, stderr);
+  fputs(" -h", stderr);
+  fputs(" [-c]", stderr);
+  fputs(" [-b blocksize]", stderr);
+  fputs(" [-e estsize]", stderr);
+  fputs(" [-f tapedev]", stderr);
+  fputs(" [-t typename]", stderr);
+  fputc('\n', stderr);
+}
+
+void help()
+{
+  usage();
+  fputs("\
+  -h                   display this message\n\
+  -c                   run hardware compression detection test only\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);
+}
+
+
+int do_tty;
+
+void show_progress(blocks, files)
+  size_t *blocks, *files;
+{
+  fprintf(stderr, "wrote %ld %dKb block%s in %ld file%s",
+         (long)*blocks, blockkb, (*blocks == 1) ? "" : "s",
+         (long)*files, (*files == 1) ? "" : "s");
+}
+
+
+void do_pass(size, blocks, files, seconds)
+  size_t size, *blocks, *files;
+  time_t *seconds;
+{
+  size_t blks;
+  time_t start, end;
+  int save_errno;
+
+  if (tapefd_rewind(fd) == -1) {
+    fprintf(stderr, "%s: could not rewind %s: %s\n",
+           sProgName, tapedev, strerror(errno));
+    exit(1);
+  }
+
+  time(&start);
+
+  while(1) {
+
+    if ((blks = writeblocks(fd, size)) <= 0 || tapefd_weof(fd, 1) != 0)
+      break;
+    *blocks += blks;
+    (*files)++;
+    if(do_tty) {
+      putc('\r', stderr);
+      show_progress(blocks, files);
+    }
+  }
+  save_errno = errno;
+
+  time(&end);
+
+  if (*blocks == 0) {
+    fprintf(stderr, "%s: could not write any data in this pass: %s\n",
+           sProgName, short_write ? "short write" : strerror(save_errno));
+    exit(1);
+  }
+
+  if(end <= start) {
+    /*
+     * Just in case time warped backward or the device is really, really
+     * fast (e.g. /dev/null testing).
+     */
+    *seconds = 1;
+  } else {
+    *seconds = end - start;
+  }
+  if(do_tty) {
+    putc('\r', stderr);
+  }
+  show_progress(blocks, files);
+  fprintf(stderr, " in %ld second%s (%s)\n",
+         (long)*seconds, ((long)*seconds == 1) ? "" : "s",
+         short_write ? "short write" : strerror(save_errno));
+}
+
+
+void do_pass0(size, seconds, dorewind)
+  size_t size;
+  time_t *seconds;
+  int dorewind;
+{
+  size_t blks;
+  time_t start, end;
+  int save_errno;
+
+  if (dorewind  &&  tapefd_rewind(fd) == -1) {
+    fprintf(stderr, "%s: could not rewind %s: %s\n",
+           sProgName, tapedev, strerror(errno));
+    exit(1);
+  }
+
+  time(&start);
+
+  blks = writeblocks(fd, size);
+  tapefd_weof(fd, 1);
+
+  save_errno = errno;
+
+  time(&end);
+
+  if (blks <= 0) {
+    fprintf(stderr, "%s: could not write any data in this pass: %s\n",
+           sProgName, short_write ? "short write" : strerror(save_errno));
+    exit(1);
+  }
+
+  if(end <= start) {
+    /*
+     * Just in case time warped backward or the device is really, really
+     * fast (e.g. /dev/null testing).
+     */
+    *seconds = 1;
+  } else {
+    *seconds = end - start;
+  }
+}
+
+
+int main(argc, argv)
+     int argc;
+     char *argv[];
+{
+  size_t pass1blocks = 0;
+  size_t pass2blocks = 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;
+  char *sizeunits;
+  int ch;
+  char *suffix;
+  char *typename;
+  time_t now;
+  int hwcompr = 0;
+  int comprtstonly = 0;
+
+  if ((sProgName = strrchr(*argv, '/')) == NULL) {
+    sProgName = *argv;
+  } else {
+    sProgName++;
+  }
+
+  estsize = 1024 * 1024;                       /* assume 1 GByte for now */
+  tapedev = getenv("TAPE");
+  typename = "unknown-tapetype";
+
+  while ((ch = getopt(argc, argv, "b:e:f:t:hc")) != 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;
+      }
+      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;
+      }
+      break;
+    case 'f':
+      tapedev = stralloc(optarg);
+      break;
+    case 't':
+      typename = stralloc(optarg);
+      break;
+    case 'c':
+      comprtstonly = 1;
+      break;
+    case 'h':
+      help();
+      return 1;
+      break;
+    default:
+      fprintf(stderr, "%s: unknown option \'%c\'\n", sProgName, ch);
+      /* fall through to ... */
+    case '?':
+      usage();
+      return 1;
+      break;
+    }
+  }
+  blocksize = blockkb * 1024;
+
+  if (tapedev == NULL || optind < argc) {
+    usage();
+    return 1;
+  }
+
+  fd = tape_open(tapedev, O_RDWR);
+  if (fd == -1) {
+    fprintf(stderr, "%s: could not open %s: %s\n",
+           sProgName, tapedev, strerror(errno));
+    return 1;
+  }
+
+  do_tty = isatty(fileno(stderr));
+
+  /*
+   * Estimate pass: write twice a small file, once with compressable
+   * data and once with uncompressable data.
+   * The theory is that if the drive is in hardware compression mode
+   * we notice a significant difference in writing speed between the two
+   * (at least if we can provide data as fast the tape streams).
+   */
+
+  initnotrandombytes();
+
+  fprintf(stderr, "Estimate phase 1...");
+  pass0size = 8 * 1024 / blockkb;
+  pass1time = 0;
+  pass2time = 0;
+  /*
+   * To get accurate results, we should write enough data
+   * so that rewind/start/stop time is small compared to
+   * the total time; let's take 10%.
+   * The timer has a 1 sec granularity, so the test
+   * should take at least 10 seconds to measure a
+   * difference with 10% accuracy; let's take 25 seconds.
+   */ 
+  while (pass1time < 25 || ((100*(pass2time-pass1time)/pass2time) >= 10) ) {
+    if (pass1time != 0) {
+      int i = pass1time;
+      do {
+         pass0size *= 2;
+         i *= 2;
+      } while (i < 25);
+    }
+    /*
+     * first a dummy pass to rewind, stop, start and
+     * get drive streaming, then do the real timing
+     */
+    do_pass0(pass0size, &pass2time, 1);
+    do_pass0(pass0size, &pass1time, 0);
+    if (pass0size >= 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);
+
+  /*
+   * now generate uncompressable data and try again
+   */
+  time(&now);
+  srandom(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);
+
+  /*
+   * Compute the time difference between writing the compressable and
+   * uncompressable data.  If it differs more than 20%, then warn
+   * user that the tape drive has probably hardware compression enabled.
+   */
+  if (pass1time > pass2time) {
+    /*
+     * Strange!  I would expect writing compresseable data to be
+     * much faster (or about equal, if hardware compression is disabled)
+     */
+    timediff = 0;
+  } else {
+    timediff = pass2time - pass1time;
+  }
+  if (((100 * timediff) / pass2time) >= 20) {  /* 20% faster? */
+    fprintf(stderr, "WARNING: Tape drive has hardware compression enabled\n");
+    hwcompr = 1;
+  }
+
+  /*
+   * Inform about estimated time needed to run the remaining of this program
+   */
+  fprintf(stderr, "Estimated time to write 2 * %d Mbyte: ", estsize / 1024);
+  pass1time = (time_t)(2.0 * pass2time * estsize / (1.0 * pass0size * 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));
+
+  if (comprtstonly) {
+       exit(hwcompr);
+  }
+
+
+  /*
+   * 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 */
+  }
+  do_pass(pass1size, &pass1blocks, &pass1files, &pass1time);
+
+  /*
+   * Do pass 2 -- write smaller files until error.
+   */
+  pass2size = pass1size / 2;
+  do_pass(pass2size, &pass2blocks, &pass2files, &pass2time);
+
+  /*
+   * Compute the size of a filemark as the difference in data written
+   * between pass 1 and pass 2 divided by the difference in number of
+   * file marks written between pass 1 and pass 2.  Note that we have
+   * to be careful in case size_t is unsigned (i.e. do not subtract
+   * things and then check for less than zero).
+   */
+  if (pass1blocks <= pass2blocks) {
+    /*
+     * If tape marks take up space, there should be fewer blocks in pass
+     * 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;
+  } else {
+    blockdiff = pass1blocks - pass2blocks;
+  }
+  if (pass2files <= pass1files) {
+    /*
+     * This should not happen, but just in case ...
+     */
+    filediff = 1;
+  } else {
+    filediff = pass2files - pass1files;
+  }
+  filemark = blockdiff * 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;
+    sizeunits = "gbytes";
+  } else if (size >= 1024 * 1000) {
+    size /= 1024;
+    sizeunits = "mbytes";
+  } else {
+    sizeunits = "kbytes";
+  }
+
+  /*
+   * Compute the speed as the average of the two passes.
+   */
+  speed = (((double)pass1blocks * blockkb / pass1time)
+           + ((double)pass2blocks * blockkb / pass2time)) / 2;
+
+  /*
+   * Dump the tapetype.
+   */
+  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("}\n");
+
+  if (tapefd_rewind(fd) == -1) {
+    fprintf(stderr, "%s: could not rewind %s: %s\n",
+           sProgName, tapedev, strerror(errno));
+    return 1;
+  }
+
+  if (tapefd_close(fd) == -1) {
+    fprintf(stderr, "%s: could not close %s: %s\n",
+           sProgName, tapedev, strerror(errno));
+    return 1;
+  }
+
+  return 0;
+}